package com.ethank.service.impl;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ethank.common.core.domain.AjaxResult;
import com.ethank.common.utils.DateUtils;
import com.ethank.common.utils.StringUtils;
import com.ethank.common.utils.uuid.UUID;
import com.ethank.mapper.ShopMapper;
import com.ethank.utils.HtmlToPdfUtils;
import com.ethank.utils.RedisUtil;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @author tf
 * @date 2024-08-28
 * @Description
 */
@Service
public class MailServiceImpl {

    @Resource
    ShopMapper shopMapper;
    @Resource
    RedisUtil redisUtil;

    private static final String PATH = System.getProperty("user.dir");

    private final static Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);

    private static final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();

    private final AtomicBoolean isCancel = new AtomicBoolean(false);
    private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
    private final List<String> specialStores = Arrays.asList("01392", "02022", "04509", "08708", "03350", "04055");

    public AjaxResult sendWithHtml(JSONObject jsonObject) {
        logger.info("=== Send mail ===");
        isCancel.set(false);

        JSONArray shopList = jsonObject.getJSONArray("ids");
        String clientId = jsonObject.getString("clientId");
        if (null == shopList || shopList.size() == 0) {
            return AjaxResult.error("门店信息不可为空");
        }
        // 获取邮件配置信息
        Object userIdObj = redisUtil.get(clientId);

        if (null == userIdObj) {
            return AjaxResult.error("无效的会话，或者会话已过期，请重新访问");
        }
        Object hostObj = redisUtil.hget(Convert.toStr(userIdObj), "host");
        Object emailSourceObj = redisUtil.hget(Convert.toStr(userIdObj), "emailSource");
        Object emailPasswordObj = redisUtil.hget(Convert.toStr(userIdObj), "emailPassword");
        Object emailPort = redisUtil.hget(Convert.toStr(userIdObj), "emailPort");

        if (StringUtils.isBlank(Convert.toStr(hostObj)) || StringUtils.isBlank(Convert.toStr(emailSourceObj))
            || StringUtils.isBlank(Convert.toStr(emailPasswordObj))) {
            return AjaxResult.error("无效的会话，请重新登陆");
        }

        logger.info("Ready to send mail ...");
        // 创建 JavaMailSender 对象
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(hostObj.toString());
        mailSender.setPort(Convert.toInt(emailPort));
        mailSender.setUsername(emailSourceObj.toString());
        mailSender.setPassword(emailPasswordObj.toString());

        // 设置其他邮件发送配置
        Properties properties = mailSender.getJavaMailProperties();
        properties.setProperty("mail.transport.protocol", "smtp");
        properties.setProperty("mail.smtp.auth", "true");
        // properties.setProperty("mail.smtp.starttls.enable", "true"); // 587端口
        properties.setProperty("mail.smtp.ssl.enable", "true"); // 465端口
        // properties.setProperty("mail.smtp.port", Convert.toStr(emailPort));
        // properties.setProperty("mail.smtp.socketFactory.port", Convert.toStr(emailPort));

        properties.setProperty("mail.smtp.port", Convert.toStr(465));
        properties.setProperty("mail.smtp.socketFactory.port", Convert.toStr(465));
        properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        properties.setProperty("mail.smtp.ssl.protocols", "TLSv1.2,TLSv1.3");

        MimeMessage mimeMessage = mailSender.createMimeMessage();

        MimeMessageHelper mimeMessageHelper = null;

        for (int i = 0; i < shopList.size(); i++) {
            JSONObject shop = shopList.getJSONObject(i);
            JSONObject mailMsg = new JSONObject();
            mailMsg.put("shopId", shop.getString("shopId"));
            mailMsg.put("shopname", shop.getString("shopname"));
            // 组装邮件主题
            String subject = "【" + shop.getString("ShopID") + "】" + shop.getString("shopname") + "-"
                + formatYm(shop.getString("Atime")) + "账单";
            if (!isCancel.get()) {
                try {
                    int randomNumber = new Random().nextInt(3) + 1;
                    // 新增数据校验业务
                    if (1 == Convert.toInt(jsonObject.getInteger("type"), 0)) {
                        Thread.sleep(randomNumber * 500);
                        HashMap<String, Object> resultMap = buildContent(shop, 2);

                        // 金额校验
                        Integer checked = Convert.toInt(resultMap.get("checked"), 0);
                        if (checked == 0) {
                            mailMsg.put("flag", "error");
                            sendUpdateToClient(clientId, mailMsg.toString());
                        } else {
                            mailMsg.put("flag", "success");
                            sendUpdateToClient(clientId, mailMsg.toString());
                        }
                        continue;
                    }
                    // 结束校验

                    Thread.sleep(randomNumber * 1000);
                    // 组装发送邮件内容
                    mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
                    logger.info("Info=>sendWithHtml=>send email shop =>[{}]==[{}]=[{}]", shop.getString("ShopID"),
                        shop.getString("shopname"), shop.getString("Email"));
                    mimeMessageHelper.setFrom(emailSourceObj.toString());
                    String email = Convert.toStr(shop.getString("Email"), "");
                    if (StringUtils.isNotBlank(shop.getString("toEmail"))) {
                        email = shop.getString("toEmail");
                    }

                    String[] filteredEmails = {};
                    if (StringUtils.isNotBlank(email)) {
                        String[] emailArray = email.split(";");
                        // 分割带";"并过滤#的邮箱
                        filteredEmails = Arrays.stream(emailArray).filter(e -> !e.contains("#")).toArray(String[]::new);

                    }


                    if (null != filteredEmails && filteredEmails.length > 0) {
                        // String[] emails={"21613620@qq.com","16612@163.com"};
                        // mimeMessageHelper.setTo(emails);
                        mimeMessageHelper.setTo(filteredEmails);
                        mimeMessageHelper.setSubject(subject);
                        HashMap<String, Object> resultMap = buildContent(shop, 1);

                        // 设置内容，并设置内容 html 格式为 true
                        String html = resultMap.get("htmlText").toString();
                        mimeMessageHelper.setText(html, true);
                        // 添加pdf附件
                        String fileName = "【" + shop.getString("ShopID") + "】" + shop.getString("shopname") + "_"
                            + formatYm(shop.getString("Atime")) + ".pdf";
                        String pdfPath = generatePdf(html);
                        File file = new File(pdfPath);
                        logger.info("INFO=>pdf=>path=>{}", pdfPath);
                        mimeMessageHelper.addAttachment(MimeUtility.encodeText(fileName), file);
                        mailSender.send(mimeMessage);
                        // 2024-08-30 1.1 更新OA邮件发送状态
                        HashMap<String, Integer> paramMap = new HashMap<>();
                        paramMap.put("fsn", Convert.toInt(shop.getInteger("FSN"), 0));
                        paramMap.put("type", 1);
                        if (StringUtils.isBlank(shop.getString("toEmail"))) {
                            // 更新邮件发送次数
                            shopMapper.updateOperate(paramMap);
                        }
                        // 1.2 推送前端进度
                        mailMsg.put("flag", "success");
                        logger.info("=== Send mail finished ==={} ", shop.getString("shopname"));
                        sendUpdateToClient(clientId, mailMsg.toString());
                    } else {
                        mailMsg.put("flag", "fail");
                        sendUpdateToClient(clientId, mailMsg.toString());
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("Send html mail error: ", e);
                    mailMsg.put("flag", "fail");
                    sendUpdateToClient(clientId, mailMsg.toString());
                }
                logger.info("## Send the mail with html success ...");
            } else {
                mailMsg.put("flag", "stop");
                sendUpdateToClient(clientId, mailMsg.toString());
                break;
            }
        }
        if (isCancel.get()) {
            isCancel.set(false);
        }
        return AjaxResult.success();
    }

    /**
     * @Description: 模版数据转换
     * @Param: [sourceType 1-邮件 发送邮账单显示最新日期，2 导出和显示有则显示没有则显示空，3-移动端详情]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-08-30
     */

    public HashMap<String, Object> buildContent(JSONObject jsonObject, Integer sourceType) throws IOException {
        // 加载邮件html模板
        InputStream resourceAsStream;
        if (sourceType.equals(3)) {
            resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("mailtemplete-mobile.html");

        } else {
            resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("mailtemplete.html");
        }
        // InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("mailtemplete.html");
        BufferedReader fileReader = new BufferedReader(new InputStreamReader(resourceAsStream, "UTF-8"));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        try {
            while ((line = fileReader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (Exception e) {
            logger.error("读取文件失败，fileName:{}", e);
        } finally {
            fileReader.close();
        }
        // 替换参数
        String htmlText = buffer.toString();
        htmlText = htmlText.replace("{{shopInfo['shopname']}}", jsonObject.getString("shopname"));
        htmlText = htmlText.replace("{{shopInfo['ShopID']}}", jsonObject.getString("ShopID"));

        // sourceType 1-邮件 发送邮账单显示最新年月，2 导出和显示有则显示没有则显示空
        String sendDate = "";
        try {
            if (1 == sourceType) {
                sendDate = DateUtil.format(DateUtil.date(), "yyyy年MM月");
            } else if (StringUtils.isNotBlank(jsonObject.getString("SendDate"))) {
                sendDate = DateUtil.format(DateUtil.parseDate(jsonObject.getString("SendDate")), "yyyy年MM月");
            }

        } catch (Exception e) {
            logger.error("日期转换失败，date:{}", jsonObject.getString("SendDate"), e);
        }
        htmlText = htmlText.replace("{{shopInfo['SendDate']}}", sendDate);
        String atime = "";
        try {

            if (3 == sourceType) {
                atime = DateUtil.format(DateUtil.parse(jsonObject.getString("Atime")), "yyyy-MM");

            } else {
                atime = DateUtil.format(DateUtil.parse(jsonObject.getString("Atime")), "yyyy年MM月");

            }

        } catch (Exception e) {
            // 将时间戮转成yyyy-MM
            // 将时间戳转换为 Instant 对象
            Instant instant = Instant.ofEpochMilli(jsonObject.getLong("Atime"));

            // 将 Instant 对象转换为 ZonedDateTime 对象，指定时区
            ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

            // 定义日期格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");

            // 格式化日期
            atime = zonedDateTime.format(formatter);

            logger.error("日期转换失败，date:{}", jsonObject.getString("Atime"), e);
        }
        htmlText = htmlText.replace("{{shopInfo['Atime']}}", atime);
        htmlText = htmlText.replace("{{shopInfo['AtimeTwo']}}", atime);
        // 本期应付金额
        BigDecimal mayPayMoney = Convert.toBigDecimal(jsonObject.getString("MayPayMoney"), BigDecimal.ZERO);
        // 前期欠款
        BigDecimal proMoney = Convert.toBigDecimal(jsonObject.getString("ProMoney"), BigDecimal.ZERO);
        // 本期费用
        BigDecimal thisMoney = Convert.toBigDecimal(jsonObject.getString("ThisMoney"), BigDecimal.ZERO);
        // 抵销预收
        BigDecimal decYS = Convert.toBigDecimal(jsonObject.getString("decYS"), BigDecimal.ZERO);
        if ((StrUtil.isNotBlank(jsonObject.getString("AccountInfo2"))
            && jsonObject.getString("AccountInfo2").contains("狮子"))) {
            mayPayMoney = Convert.toBigDecimal(jsonObject.getString("MayPayMoney"), BigDecimal.ZERO)
                .add(Convert.toBigDecimal(jsonObject.getString("decYSGZ"), BigDecimal.ZERO))
                .add(Convert.toBigDecimal(jsonObject.getString("ProMoneyGZ"), BigDecimal.ZERO))
                .add(Convert.toBigDecimal(jsonObject.getString("ThisMoneyGZ"), BigDecimal.ZERO));

            proMoney = Convert.toBigDecimal(jsonObject.getString("ProMoney"), BigDecimal.ZERO)
                .add(Convert.toBigDecimal(jsonObject.getString("ProMoneyGZ"), BigDecimal.ZERO));
            thisMoney = Convert.toBigDecimal(jsonObject.getString("ThisMoney"), BigDecimal.ZERO)
                .add(Convert.toBigDecimal(jsonObject.getString("ThisMoneyGZ"), BigDecimal.ZERO));
            decYS = Convert.toBigDecimal(jsonObject.getString("decYS"), BigDecimal.ZERO)
                .add(Convert.toBigDecimal(jsonObject.getString("decYSGZ"), BigDecimal.ZERO));
        }
        if (null != mayPayMoney && mayPayMoney.compareTo(BigDecimal.ZERO) < 0) {
            htmlText = htmlText.replace("{{shopInfo['MayPayMoney']}}", "0.00");
        } else {
            htmlText = htmlText.replace("{{shopInfo['MayPayMoney']}}",
                mayPayMoney.setScale(2, RoundingMode.HALF_UP).toString());
        }

        htmlText = htmlText.replace("{{shopInfo['ProMoney']}}", proMoney.setScale(2, RoundingMode.HALF_UP).toString());

        htmlText =
            htmlText.replace("{{shopInfo['ThisMoney']}}", thisMoney.setScale(2, RoundingMode.HALF_UP).toString());
        // 冲预收
        htmlText = htmlText.replace("{{shopInfo['decYS']}}", decYS.setScale(2, RoundingMode.HALF_UP).toString());

        // 账户信息
        htmlText =
            htmlText.replace("{{shopInfo['AccountInfo']}}", Convert.toStr(jsonObject.getString("AccountInfo"), ""));
        // 帐户总金额
        htmlText = htmlText.replace("{{totalOneFee}}", getAccountOneAmount(jsonObject));
        // 商标许可使用费-本期应收金额
        BigDecimal account_02 =
            Convert.toBigDecimal(jsonObject.getString("02"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_07 =
            Convert.toBigDecimal(jsonObject.getString("07"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_18 =
            Convert.toBigDecimal(jsonObject.getString("18"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_21 =
            Convert.toBigDecimal(jsonObject.getString("21"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_20 =
            Convert.toBigDecimal(jsonObject.getString("20"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_26 =
            Convert.toBigDecimal(jsonObject.getString("26"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_27 =
            Convert.toBigDecimal(jsonObject.getString("27"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        // 商标许可使用费-本期金额
        htmlText = htmlText.replace("{{brandCurrentFee}}", account_02.toString());
        // 商标许可使用费-计费标准
        htmlText = htmlText.replace("{{brandStandard}}",
            replaceStr(jsonObject.getString("roomfee"), Convert
                .toBigDecimal(jsonObject.getString("01"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString(),
                "营业收入"));
        // 商标许可使用费-前期余额
        htmlText = htmlText.replace("{{brandBalance}}", balanceTip(jsonObject.getString("YSroomfee")));
        // 商标许可使用费-应付金额
        htmlText = htmlText.replace("{{brandShouldPay}}",
            calcShouldPay(jsonObject.getString("YSroomfee"), jsonObject.getString("02"), 2, jsonObject));
        // 运营质检费-本期金额
        htmlText = htmlText.replace("{{operateCurrentFee}}", account_07.toString());

        // 运营质检费-前期余额
        htmlText = htmlText.replace("{{operateBalance}}", balanceTip(jsonObject.getString("YSzhijian")));
        // 运营质检费-应付金额
        htmlText = htmlText.replace("{{operateShouldPay}}",
            calcShouldPay(jsonObject.getString("YSzhijian"), jsonObject.getString("07"), 7, jsonObject));

        // 市场营销费-本期费用
        htmlText = htmlText.replace("{{marketCurrentFee}}", account_18.toString());
        // 市场营销费-计费标准
        htmlText = htmlText.replace("{{formatMarket}}",
            replaceStr(jsonObject.getString("SCYXfee"), Convert
                .toBigDecimal(jsonObject.getString("01"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString(),
                "营业收入"));

        // 市场营销费-前期余额
        htmlText = htmlText.replace("{{marketBalance}}", balanceTip(jsonObject.getString("YSYingXiao")));
        // 市场营销费-应付金额
        htmlText = htmlText.replace("{{marketShouldPay}}",
            calcShouldPay(jsonObject.getString("YSYingXiao"), jsonObject.getString("18"), 18, jsonObject));

        // 运营顾问费-本期金额
        htmlText = htmlText.replace("{{adviserCurrentFee}}", account_21.toString());
        // 运营顾问费-前期余额
        htmlText = htmlText.replace("{{adviserBalance}}", balanceTip(jsonObject.getString("YYGUWen")));
        // 运营顾问费-应付金额
        htmlText = htmlText.replace("{{adviserShouldPay}}",
            calcShouldPay(jsonObject.getString("YYGUWen"), jsonObject.getString("21"), 21, jsonObject));

        // 品质督导费-本期金额
        htmlText = htmlText.replace("{{qualityCurrentFee}}", account_20.toString());
        // 品质督导费-计费标准
        htmlText = htmlText.replace("{{shopInfo['PZDDfee']}}",
            replaceStr(jsonObject.getString("PZDDfee"), Convert
                .toBigDecimal(jsonObject.getString("01"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString(),
                "营业收入"));
        // 品质督导费-前期余额
        htmlText = htmlText.replace("{{qualityBalance}}", balanceTip(jsonObject.getString("YSDuDao")));
        // 品质督导费-应付金额
        htmlText = htmlText.replace("{{qualityShouldPay}}",
            calcShouldPay(jsonObject.getString("YSDuDao"), jsonObject.getString("20"), 20, jsonObject));

        // 舆情系统使用费-本金额

        htmlText = htmlText.replace("{{sentimentCurrentFee}}", account_26.toString());

        // 舆情系统使用费-前期余额
        htmlText = htmlText.replace("{{sentimentBalance}}", balanceTip(jsonObject.getString("ysyuqingfee")));
        // 舆情系统使用费-应付金额
        htmlText = htmlText.replace("{{sentimentShouldPay}}",
            calcShouldPay(jsonObject.getString("ysyuqingfee"), jsonObject.getString("26"), 26, jsonObject));
        // 财务咨询

        // 财务咨询-本期金额
        htmlText = htmlText.replace("{{shopInfo['27']}}", account_27.toString());
        // 财务咨询-计费标准
        htmlText = htmlText.replace("{{shopInfo['CWZXfee']}}", Convert.toStr(jsonObject.getString("CWZXfee"), ""));
        // 财务咨询-前期余额
        htmlText = htmlText.replace("{{financeBalance}}", balanceTip(jsonObject.getString("yscaiwufee")));
        // 财务咨询-应付金额
        htmlText = htmlText.replace("{{financeShouldPay}}",
            calcShouldPay(jsonObject.getString("yscaiwufee"), jsonObject.getString("27"), 27, jsonObject));

        // 上海腾容
        BigDecimal account_08 =
            Convert.toBigDecimal(jsonObject.getString("08"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_06 =
            Convert.toBigDecimal(jsonObject.getString("06"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_29 =
            Convert.toBigDecimal(jsonObject.getString("29"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_12 =
            Convert.toBigDecimal(jsonObject.getString("12"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_30 =
            Convert.toBigDecimal(jsonObject.getString("30"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_04 =
            Convert.toBigDecimal(jsonObject.getString("04"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        BigDecimal account_22 =
            Convert.toBigDecimal(jsonObject.getString("22"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        // 合计
        htmlText = htmlText.replace("{{totalTwoFee}}", getTotalTwoFee(jsonObject, 1));
        // Ai 经营管家服务名称
        String systemname = "AI经营管家服务费";
        if (Convert.toBool(jsonObject.getString("xindongli"), Boolean.FALSE)) {
            systemname = jsonObject.getString("systemname");
        }
        htmlText = htmlText.replace("{{systemName}}", systemname);
        // AI经营管家服务费-本期费用
        htmlText = htmlText.replace("{{aiCurrentFee}}", account_08.toString());
        // AI经营管家服务费-计算标准
        htmlText = htmlText.replace("{{aiStandard}}", Convert.toStr(jsonObject.getString("systemfee"), ""));
        // AI经营管家服务费-欠款
        htmlText = htmlText.replace("{{aiBalance}}", balanceTip(jsonObject.getString("YSsystemFee")));
        // AI经营管家服务费-本期应收金额
        htmlText = htmlText.replace("{{aiShouldPay}}",
            calcShouldPay(jsonObject.getString("YSsystemFee"), account_08.toString(), 8, jsonObject));
        // 输送客源费-本期费用合计
        htmlText = htmlText.replace("{{transportCurrentFee}}",
            account_06.add(Convert.toBigDecimal(jsonObject.getString("23"), BigDecimal.ZERO)).add(account_29)
                .add(Convert.toBigDecimal(jsonObject.getString("31"), BigDecimal.ZERO))
                .setScale(2, BigDecimal.ROUND_HALF_UP).toString());

        // 输送客源费-前期欠款总计

        htmlText = htmlText.replace("{{transportBalance}}",
            balanceTip(Convert.toBigDecimal(jsonObject.getString("YSbookfee"), BigDecimal.ZERO)
                .add(Convert.toBigDecimal(jsonObject.getString("ysBookJM"), BigDecimal.ZERO)).toString()));
        // 输送客源费-本期应收金额总计
        htmlText = htmlText.replace("{{transportShouldPay}}", getTransportShouldPay(jsonObject));

        // 线上订单中央输送费金额-本期金额
        htmlText = htmlText.replace("{{onlineCurrentFee}}", Convert
            .toBigDecimal(jsonObject.getString("31"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 线上订单中央输送费金额-计算基数
        htmlText = htmlText.replace("{{shopInfo['bookfee2']}}", Convert.toStr(jsonObject.getString("bookfee2")));
        // 线下订单中央输送费金额-本期费用
        htmlText = htmlText.replace("{{offlineCurrentFee}}", Convert
            .toBigDecimal(jsonObject.getString("06"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 线下订单中央输送费金额-计费标准
        htmlText = htmlText.replace("{{offlineStandard}}",
            replaceOrderStr(jsonObject.getString("bookfee"), Convert
                .toBigDecimal(jsonObject.getString("17"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString(),
                "中央订单金额:"));

        // 线下订单中央输送费金额-欠款
        htmlText = htmlText.replace("{{offlineBalance}}", balanceTip(jsonObject.getString("YSbookfee")));
        // 线下订单中央输送费金额-本期应收
        htmlText = htmlText.replace("{{offlineShouldPay}}",
            calcShouldPay(jsonObject.getString("YSbookfee"), account_06.toString(), 6, jsonObject));
        // 9.3输送客源费减免-本期应收金额
        htmlText = htmlText.replace("{{shopInfo['29']}}", account_29.toString());
        // 输送客源计费标准
        String sskyjm = Convert.toStr(jsonObject.getString("YJdecMemo"), "");
        htmlText =
            htmlText.replace("{{shopInfo['YJdecMemo']}}", StringUtils.isBlank(sskyjm) ? "" : "根据当前减免政策，" + sskyjm);
        // 9.3输送客源费减免-前期欠款
        htmlText = htmlText.replace("{{freeBalance}}", balanceTip(jsonObject.getString("ysBookJM")));
        // 输送客源减免-本期应付
        htmlText = htmlText.replace("{{freeShouldPay}}",
            calcShouldPay(jsonObject.getString("ysBookJM"), jsonObject.getString("29"), 29, jsonObject));
        // 售卡佣金返还-本期费用
        htmlText = htmlText.replace("{{shopInfo['23']}}", Convert
            .toBigDecimal(jsonObject.getString("23"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 售卡佣金-计费标准
        htmlText = htmlText.replace("{{kickbackStandard}}", Convert.toStr(jsonObject.getString("FYdecMemo"), ""));
        // 售卡佣金-欠款
        htmlText = htmlText.replace("{{kickbackBalance}}", balanceTip(jsonObject.getString("ysyjjmfee")));
        // 售卡佣金-本期应付
        htmlText = htmlText.replace("{{kickbackShouldPay}}",
            calcShouldPay(jsonObject.getString("ysyjjmfee"), jsonObject.getString("23"), 23, jsonObject));
        // 会员管理-本期应收
        htmlText = htmlText.replace("{{memberCurrentFee}}", account_04.add(account_22).add(account_30).toString());

        // 会员管理-欠款总计
        BigDecimal memberBalance = Convert.toBigDecimal(jsonObject.getString("YSjifen"), BigDecimal.ZERO)
            .add(Convert.toBigDecimal(jsonObject.getString("JFDX3"), BigDecimal.ZERO))
            .add(Convert.toBigDecimal(jsonObject.getString("ysIntegralJM"), BigDecimal.ZERO));
        htmlText = htmlText.replace("{{memberBalance}}", balanceTip(memberBalance.toString()));
        // 会员管理-本期应付总计
        htmlText = htmlText.replace("{{memberShouldPay}}", getMemberShouldPay(jsonObject));

        // 积分管理费-本期费用
        htmlText = htmlText.replace("{{integralCurrentFee}}", Convert
            .toBigDecimal(jsonObject.getString("04"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 积分管理费-计费标准
        htmlText = htmlText.replace("{{integralStandard}}",
            replaceStr(jsonObject.getString("jifen"), Convert.toBigDecimal(jsonObject.getString("03"), BigDecimal.ZERO)
                .setScale(2, RoundingMode.HALF_UP).toString(), "本月新增积分:"));
        // 积分管理费 -欠款
        htmlText = htmlText.replace("{{integralBalance}}", balanceTip(jsonObject.getString("YSjifen")));
        // 积分管理费 -本期应用
        htmlText = htmlText.replace("{{integralShouldPay}}",
            calcShouldPay(jsonObject.getString("YSjifen"), jsonObject.getString("04"), 4, jsonObject));

        // 积分抵现金额-本期应收
        htmlText = htmlText.replace("{{cashCurrentFee}}", account_22.toString());
        // 积分抵现金额-欠款
        htmlText = htmlText.replace("{{cashBalance}}", balanceTip(jsonObject.getString("JFDX3")));
        // 积分抵现金额-本期应付
        htmlText = htmlText.replace("{{cashShouldPay}}",
            calcShouldPay(jsonObject.getString("JFDX3"), jsonObject.getString("22"), 22, jsonObject));

        // 会员管理-会员管理减免-本期费用
        htmlText = htmlText.replace("{{memberFreeCurrentFee}}", account_30.toString());
        // 会员管理减免-计费标准
        htmlText = htmlText.replace("{{memberFreeStandard}}", Convert.toStr(jsonObject.getString("JFdecMemo"), ""));
        // 会员管理费减免-前期欠款
        htmlText = htmlText.replace("{{memberFreeBalance}}", balanceTip(jsonObject.getString("ysIntegralJM")));
        // 会员管理费减免-本期应收
        htmlText = htmlText.replace("{{memberFreeShouldPay}}",
            calcShouldPay(jsonObject.getString("ysIntegralJM"), jsonObject.getString("30"), 30, jsonObject));
        // 三.账户信息

        // htmlText = htmlText.replace("{{shopInfo['AccountInfo2']}}",
        // Convert.toStr(jsonObject.getString("AccountInfo2"), ""));
        // 合计
        // 店长工资-本期费用总计
        htmlText = htmlText.replace("{{shopManagerSalary}}", getShopManagerSalary(jsonObject));

        // 店长工资-前期欠款总计
        htmlText = htmlText.replace("{{shopManagerBalance}}", balanceTip(shopManagerBalance(jsonObject)));
        htmlText = htmlText.replace("{{shopManagerSalaryShouldPay}}", getShopManagerSalaryShouldPay(jsonObject,1));
        // 店长工资-当前月份
        htmlText = htmlText.replace("{{getYearMonth}}", getYearMonth(jsonObject, 1));
        // 店长基本工资-本期费用/本期应收
        htmlText = htmlText.replace("{{shopInfo['gongziNum']}}",
            Convert.toBigDecimal(jsonObject.getString("gongziNum"), BigDecimal.ZERO)
                .setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        htmlText = htmlText.replace("{{getBaseGongZiPay}}",
            Convert.toBigDecimal(jsonObject.getString("gongziNum"), BigDecimal.ZERO)
                .setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        // 店长工资-计费标准
        htmlText = htmlText.replace("{{shopInfo['GongZiFee']}}", Convert.toStr(jsonObject.getString("GongZiFee"), ""));
        // 店长工资-实际工资
        htmlText = htmlText.replace("{{beforeMonth}}", getYearMonth(jsonObject, 0));
        // 店长工资-实际本期费用
        htmlText = htmlText.replace("{{shopInfo['19']}}", Convert
            .toBigDecimal(jsonObject.getString("19"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 店长工资-实际工资计费标准
        htmlText = htmlText.replace("{{shopInfo['GZdecMemo']}}", Convert.toStr(jsonObject.getString("GZdecMemo"), ""));
        // 店长工资-实际欠款
        htmlText = htmlText.replace("{{actualBasicSalary}}", balanceTip(jsonObject.getString("YSGongZi")));
        // 店长工资-实际应收
        htmlText = htmlText.replace("{{shopManagerSalaryBasic}}",
            calcShouldPay(jsonObject.getString("YSGongZi"), jsonObject.getString("19"), 19, jsonObject));
        // 店长工资- 工资季度调整-本期应收
        htmlText = htmlText.replace("{{shopInfo['28']}}", Convert
            .toBigDecimal(jsonObject.getString("28"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());

        // 店长工资-绩效工资-本期应收
        BigDecimal account_16 =
            Convert.toBigDecimal(jsonObject.getString("16"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        htmlText = htmlText.replace("{{shopInfo['16']}}", account_16.toString());
        // 店长工资-绩效工资-计费标准
        if (account_16.compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("{{meritPayTip}}", "出租率奖金");
        } else {
            htmlText = htmlText.replace("{{meritPayTip}}", "/");
        }
        // 店长工资-绩效工资-前期欠款
        htmlText = htmlText.replace("{{shopInfo['YSJixiao']}}", balanceTip(jsonObject.getString("YSJixiao")));
        // 店长工资-绩效工资-本期应付
        htmlText = htmlText.replace("{{meritShouldPayAmount}}",
            calcShouldPay(jsonObject.getString("YSJixiao"), jsonObject.getString("16"), 16, jsonObject));

        // 营销经理账务公司
        htmlText = htmlText.replace("{{getFourAccount}}", Convert.toStr(getFourAccountNumber(jsonObject), ""));
        htmlText = htmlText.replace("{{accountInfo3}}", Convert.toStr(jsonObject.getString("AccountInfo3"), ""));
        // 账务公司四是否显示
        logger.info("getIsDiff=>" + getIsDiffCompany(jsonObject));
        logger.info("getDzDisplay=" + !getDzDisplay(jsonObject));
        if ((getIsDiffCompany(jsonObject) || !getDzDisplay(jsonObject)) && getYxIsDisplay(jsonObject)) {
            htmlText = htmlText.replace("four_account_hiddenBox", "");
        } else {
            htmlText = htmlText.replace("four_account_hiddenBox'", "' style='display:none'");
        }

        // 营销经理-本期费用总计
        htmlText = htmlText.replace("{{getYxCurrentAmount}}", getYxCurrentAmount(jsonObject));
        // 营销经理-计费过程总计
        // htmlText = htmlText.replace("{{getYxFeeProcess}}", getYxFeeProcess(jsonObject));
        // 营销经理-前期欠款总计
        htmlText = htmlText.replace("{{getYxPreBalance}}", balanceTip(getYxPreBalance(jsonObject)));
        // 营销经理-本期应付总计
        htmlText = htmlText.replace("{{getYxSalary}}", getYxSalary(jsonObject, 0));
        htmlText = htmlText.replace("{{getYxTotalSalary}}", getYxSalary(jsonObject, 0));
        // 营销经理-基本工资
        htmlText = htmlText.replace("{{shopInfo['yingxiaoGzNum']}}",
            Convert.toBigDecimal(jsonObject.getString("yingxiaoGzNum"), BigDecimal.ZERO)
                .setScale(2, RoundingMode.HALF_UP).toString());

        htmlText = htmlText.replace("{{getYxBasicSalaryPay}}",
            Convert.toBigDecimal(jsonObject.getString("yingxiaoGzNum"), BigDecimal.ZERO)
                .setScale(2, RoundingMode.HALF_UP).toString());
        // 营销经理-基本工资计费过程
        htmlText =
            htmlText.replace("{{shopInfo['YingXiaoGzFee']}}", Convert.toStr(jsonObject.getString("YingXiaoGzFee"), ""));
        // 营销经理-实际工资-本期费用
        htmlText = htmlText.replace("{{shopInfo['39']}}", Convert
            .toBigDecimal(jsonObject.getString("39"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 营销经理-实际工资-计费标准
        htmlText = htmlText.replace("{{shopInfo['yingxiaoGZdecMemo']}}",
            Convert.toStr(jsonObject.getString("yingxiaoGZdecMemo"), ""));
        // 营销经理-实际工资-前期欠款
        htmlText = htmlText.replace("{{ysActBasicSalaryBalance}}", balanceTip(jsonObject.getString("YSGongZiYX")));
        // 营销经理-实际工资-应付费用
        htmlText = htmlText.replace("{{yxSalaryActBasic}}",
            calcShouldPay(jsonObject.getString("YSGongZiYX"), jsonObject.getString("39"), 39, jsonObject));

        // 营销经理-季度调整
        htmlText = htmlText.replace("{{shopInfo['38']}}", Convert
            .toBigDecimal(jsonObject.getString("38"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());

        // 营销经理-绩效本费用
        htmlText = htmlText.replace("{{shopInfo['36']}}", Convert
            .toBigDecimal(jsonObject.getString("36"), BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP).toString());
        // 营销经理-绩效-计费标准
        String yxMeritPayTip = "/";
        if (Convert.toBigDecimal(jsonObject.getString("36"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            yxMeritPayTip = "出租率奖金";
        }
        // 公司三总应付费用
        htmlText = htmlText.replace("{{getDzTotalMoney}}", getDzTotalMoney(jsonObject, 0));

        htmlText = htmlText.replace("{{yxMeritPayTip}}", yxMeritPayTip);
        // 营销经理-绩效-前期欠款
        htmlText = htmlText.replace("{{yxJixiaoBalance}}", balanceTip(jsonObject.getString("YSJixiaoYX")));
        // 营销经理-绩效-应付
        htmlText = htmlText.replace("{{yxMeritPayShouldPay}}",
            calcShouldPay(jsonObject.getString("YSJixiaoYX"), jsonObject.getString("36"), 36, jsonObject));
        // 开票单位一
        htmlText = htmlText.replace("{{shopInfo.Rate1}}", Convert.toStr(jsonObject.getString("Rate1"), ""));
        // 开票单位 总费用
        htmlText = htmlText.replace("{{invoiceOneAmount}}", getAccountOneAmount(jsonObject));
        // 开票单位一开户行
        htmlText = htmlText.replace("{{shopInfo.accountno1}}", Convert.toStr(jsonObject.getString("accountno1"), ""));
        // 开票单位一收款账号
        htmlText = htmlText.replace("{{shopInfo.bankname1}}", Convert.toStr(jsonObject.getString("bankname1"), ""));
        // 开票单位二总费用
        htmlText = htmlText.replace("{{invoiceTwoAmount}}", getTotalTwoFee(jsonObject, 3));
        // 开票单位三帐户名称

        String invoiceThreeName = Convert.toStr(jsonObject.getString("AccountInfo2"), "");
        String invoiceThreeBank = Convert.toStr(jsonObject.getString("bankname2"), "");
        String invoiceThreeBankAccount = Convert.toStr(jsonObject.getString("accountno2"), "");
        if (StringUtils.isNotBlank(invoiceThreeName) && invoiceThreeName.contains("狮子")) {
            invoiceThreeName = "-";
        }
        htmlText = htmlText.replace("{{invoiceThreeName}}", invoiceThreeName);

        // 开票单位三收款账号

        htmlText = htmlText.replace("{{invoiceThreeBankAccount}}", invoiceThreeBankAccount);
        htmlText = htmlText.replace("{{getDzTotalMoney2}}", getDzTotalMoney(jsonObject, 1));

        // 开票单位三开户行名称
        htmlText = htmlText.replace("{{invoiceThreeBank}}", invoiceThreeBank);
        // 公司三是否显示
        if (getDzDisplay(jsonObject)) {
            htmlText = htmlText.replace("three_account_hidden", "");
        } else {
            htmlText = htmlText.replace("three_account_hidden'", "three_account_hidden' style='display:none'");
        }
        // 公司四
        htmlText = htmlText.replace("{{invoiceFourName}}", Convert.toStr(jsonObject.getString("AccountInfo3"), ""));
        htmlText = htmlText.replace("{{invoiceFourBank}}", Convert.toStr(jsonObject.getString("bankname3"), ""));
        htmlText =
            htmlText.replace("{{invoiceFourBankAccount}}", Convert.toStr(jsonObject.getString("accountno3"), ""));
        htmlText = htmlText.replace("{{getYxTotalMoney}}", getYxSalary(jsonObject, 1));

        // 签名
        htmlText = htmlText.replace("{{shopInfo.sign}}", Convert.toStr(jsonObject.getString("sign"), ""));
        // 费用调整说明

        if (StringUtils.isNotBlank(jsonObject.getString("MemoTZ"))) {
            htmlText = htmlText.replace("memoTz_hiddenBox", "");
            String memoTZ = Convert.toStr(jsonObject.getString("MemoTZ"), "");
            // 去除两边空格;字符串 amp;&#x0D;
            memoTZ = memoTZ.trim().replaceAll("amp;", "").replaceAll("&#x0D;", "").replaceAll("&", "，");
            htmlText = htmlText.replace("{{memoTZ}}", memoTZ);

        } else {
            htmlText = htmlText.replace("4、{{memoTZ}}。", "");
        }
        //todo 网络
        if (StringUtils.isNotBlank(jsonObject.getString("MemoTZ"))) {
            htmlText = htmlText.replace("{{networkDescNumber}}", "5、");
        }else{
            htmlText = htmlText.replace("{{networkDescNumber}}", "4、");
             }
          htmlText = htmlText.replace("{{networkUrl}}",  "https://support.sunmeihotel.com/bill/network");
        // 链接配置
        try {
            String sign = DigestUtils.md5DigestAsHex(
                ("sunmeiEmail" + jsonObject.getString("ShopID") + formatYm(jsonObject.getString("Atime")))
                    .getBytes("UTF-8"));
            String signFsn = DigestUtils
                .md5DigestAsHex(("sunmeiEmail" + jsonObject.getString("FSN") + formatYm(jsonObject.getString("Atime")))
                    .getBytes("UTF-8"));
            String cashUrl = "https://support.sunmeihotel.com/bill/cash?shopId=" + jsonObject.getString("ShopID")
                + "&atime=" + formatYm(jsonObject.getString("Atime")) + "&sign=" + sign;
            String offline = "https://support.sunmeihotel.com/bill/offline?shopId=" + jsonObject.getString("ShopID")
                + "&atime=" + formatYm(jsonObject.getString("Atime")) + "&sign=" + sign;
            String online = "https://support.sunmeihotel.com/bill/online?shopId=" + jsonObject.getString("ShopID")
                + "&atime=" + formatYm(jsonObject.getString("Atime")) + "&sign=" + sign;
            String qaUrl = "https://support.sunmeihotel.com/bill/qa";
            // String shareUrl = "https://support.sunmeihotel.com/bill/member?shopId=" + jsonObject.getString("FSN")
            // +"&sign=" + sign;
            String shareUrl = "https://support.sunmeihotel.com/bill/member?shopId=" + jsonObject.getString("FSN")
                + "&atime=" + formatYm(jsonObject.getString("Atime")) + "&sign=" + signFsn;
            logger.info("cashUrl=" + cashUrl + "=onlineUrl=" + offline);
            htmlText = htmlText.replace("{{cashUrl}}", cashUrl);
            htmlText = htmlText.replace("{{onlineUrl}}", online);
            htmlText = htmlText.replace("{{offlineUrl}}", offline);
            htmlText = htmlText.replace("{{qaUrl}}", qaUrl);
            htmlText = htmlText.replace("{{shareUrl}}", shareUrl);
        } catch (Exception ex) {
            logger.error("链接生成失败", ex);
        }
        // 2-运营质检费
        // int rowHiddenCount = 0;
        int currentRow = 1;
        if (Convert.toBigDecimal(jsonObject.getString("YSzhijian"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("YSzhijian"), jsonObject.getString("07"), 7, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("yyzj_hiddenBox", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{operateNumber}}", String.valueOf(currentRow));

        } else {
            htmlText = htmlText.replace("yyzj_hiddenBox'", "yyzj_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("{{operateNumber}}", "-");
        }
        // 3-市场营销序号
        if (Convert.toBigDecimal(jsonObject.getString("18"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(jsonObject.getString("YSYingXiao"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("scyx_hiddenBox", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{marketNumber}}", String.valueOf(currentRow));

        } else {
            htmlText = htmlText.replace("scyx_hiddenBox'", "scyx_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("{{marketNumber}}", "-");
        }
        // 4-运营顾问费序号
        if (Convert.toBigDecimal(jsonObject.getString("21"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YYGUWen"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("yygw_hiddenBox", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{adviserNumber}}", String.valueOf(currentRow));

        } else {
            htmlText = htmlText.replace("yygw_hiddenBox'", "yygw_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("{{adviserNumber}}", "-");

        }

        // 5-运营顾问费序号
        if (Convert.toBigDecimal(jsonObject.getString("20"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YSDuDao"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("pzdd_hiddenBox", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{qualityNumber}}", String.valueOf(currentRow));

        } else {
            htmlText = htmlText.replace("pzdd_hiddenBox'", "pzdd_hiddenBox' style='display:none'");

            htmlText = htmlText.replace("{{qualityNumber}}", "-");

        }

        // 6-舆情系统使用费序号
        if (Convert.toBigDecimal(jsonObject.getString("26"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(jsonObject.getString("ysyuqingfee"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("yqxt_hiddenBox", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{sentimentNumber}}", String.valueOf(currentRow));

        } else {
            htmlText = htmlText.replace("yqxt_hiddenBox'", "yqxt_hiddenBox' style='display:none'");

            htmlText = htmlText.replace("{{sentimentNumber}}", "-");
        }
        // 7-财务咨询费序号
        if (Convert.toBigDecimal(jsonObject.getString("27"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(jsonObject.getString("yscaiwufee"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            htmlText = htmlText.replace("cwzx_hiddenBox", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{financeNumber}}", String.valueOf(currentRow));

        } else {
            htmlText = htmlText.replace("cwzx_hiddenBox'", "cwzx_hiddenBox' style='display:none'");

            htmlText = htmlText.replace("{{financeNumber}}", "-");

        }
        // 8-ai管家序号
        currentRow += 1;
        htmlText = htmlText.replace("{{aiNumber}}", String.valueOf(currentRow));
        // 9-输送客源序号
        if (getSskyIsDisplay(jsonObject)) {
            htmlText = htmlText.replace("ssky_hiddenBox", "");
            htmlText = htmlText.replace("ssky_hiddenBox1", "");
            htmlText = htmlText.replace("ssky_hiddenBox2", "");
            currentRow += 1;
            String sskyfee = "";
            htmlText = htmlText.replace("{{transportNumber}}", String.valueOf(currentRow));
            // 输送客源费减免
            boolean isFree = false;
            sskyfee = sskyfee + currentRow + ".1线上订单预订佣金+" + currentRow + ".2线下订单中央输送费金额";
            if (Convert.toBigDecimal(jsonObject.getString("YJdecMemo"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
                || Convert.toBigDecimal(jsonObject.getString("29")).compareTo(BigDecimal.ZERO) != 0) {
                htmlText = htmlText.replace("transport_free_hidden", "");
                isFree = true;
                sskyfee = sskyfee + '+' + currentRow + ".3输送客源费减免";
            } else {
                htmlText = htmlText.replace("transport_free_hidden'", "transport_free_hidden' style='display:none'");

            }
            // 售卡佣金返还
            if (Convert.toBigDecimal(jsonObject.getString("ysyjjmfee"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
                || Convert.toBigDecimal(jsonObject.getString("23")).compareTo(BigDecimal.ZERO) != 0) {
                htmlText = htmlText.replace("kickback_hidden", "");
                if (isFree) {
                    htmlText = htmlText.replace("{{kickbackNumber}}", String.valueOf(currentRow) + ".4");
                    sskyfee = sskyfee + '+' + currentRow + ".4售卡佣金返还";
                } else {
                    htmlText = htmlText.replace("{{kickbackNumber}}", String.valueOf(currentRow) + ".3");
                    sskyfee = sskyfee + '+' + currentRow + ".3售卡佣金返还";
                }
            } else {
                htmlText = htmlText.replace("kickback_hidden'", "kickback_hidden' style='display:none'");
                htmlText = htmlText.replace("{{kickbackNumber}}", "-");
            }
            // 输入客源-计费标准总计
            htmlText = htmlText.replace("{{transportStandard}}", sskyfee);

        } else {
            htmlText = htmlText.replace("ssky_hiddenBox'", " ssky_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("ssky_hiddenBox1'", "ssky_hiddenBox1' style='display:none'");
            htmlText = htmlText.replace("ssky_hiddenBox2'", "ssky_hiddenBox2' style='display:none'");
            htmlText = htmlText.replace("kickback_hidden'", "kickback_hidden' style='display:none'");
            htmlText = htmlText.replace("transport_free_hidden'", "transport_free_hidden' style='display:none'");
            htmlText = htmlText.replace("{{kickbackNumber}}", "-");
        }
        // 10-会员管理费序号
        if (getHyglDisplay(jsonObject)) {
            htmlText = htmlText.replace("hygl_hiddenBox", "");
            htmlText = htmlText.replace("hygl_hiddenBox1", "");
            htmlText = htmlText.replace("hygl_hiddenBox2", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{memberNumber}}", String.valueOf(currentRow));
            String hyglfee = "";
            hyglfee = hyglfee + currentRow + ".1积分管理费+" + currentRow + ".2积分抵现金额";

            if (Convert.toBigDecimal(jsonObject.getString("30"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
                || Convert.toBigDecimal(jsonObject.getString("ysIntegralJM"), BigDecimal.ZERO)
                    .compareTo(BigDecimal.ZERO) != 0) {
                htmlText = htmlText.replace("member_free_hiddenBox", "");
                hyglfee = hyglfee + '+' + currentRow + ".3会员管理费减免";
            } else {
                htmlText = htmlText.replace("member_free_hiddenBox'", " member_free_hiddenBox' style='display:none'");

            }
            // 会员管理-计费标准总计
            htmlText = htmlText.replace("{{memberStandard}}", hyglfee);
        } else {
            htmlText = htmlText.replace("hygl_hiddenBox'", "hygl_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("hygl_hiddenBox1'", "hygl_hiddenBox1' style='display:none'");
            htmlText = htmlText.replace("hygl_hiddenBox2'", "hygl_hiddenBox2' style='display:none'");
            htmlText = htmlText.replace("member_free_hiddenBox'", "member_free_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("{{memberNumber}}", "-");
        }
        // 11-店长工资序号

        if (getDzDisplay(jsonObject)) {
            String dzfee = "";
            htmlText = htmlText.replace("dzgz_hiddenBox", "");
            htmlText = htmlText.replace("dzgz_hiddenBox1", "");
            htmlText = htmlText.replace("dzgz_hiddenBox2", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{dzgz_rownumber}}", String.valueOf(currentRow));
            // 店长工资-计费过程
            dzfee = dzfee + currentRow + ".1 " + getYearMonth(jsonObject, 1) + "基本工资+" + currentRow + ".2 "
                + getYearMonth(jsonObject, 0) + "实际基本工资";
            // 季度调整序号
            boolean isAdjust = false;
            if (Convert.toBigDecimal(jsonObject.getString("28"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
                isAdjust = true;
                htmlText = htmlText.replace("dzgz_adjust_hiddenBox", "");
                dzfee = dzfee + '+' + currentRow + ".3季度调整工资";
            } else {
                htmlText = htmlText.replace("dzgz_adjust_hiddenBox'", "' style='display:none'");

            }
            // 绩效序号
            if (Convert.toBigDecimal(jsonObject.getString("YSJixiao"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
                || Convert.toBigDecimal(jsonObject.getString("16"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
                htmlText = htmlText.replace("dzgz_merit_hiddenBox", "");
                if (isAdjust) {
                    htmlText = htmlText.replace("{{getMeritPayNum}}", String.valueOf(currentRow) + ".4");
                    dzfee = dzfee + "+" + currentRow + ".4" + getYearMonth(jsonObject, 0) + "绩效工资";
                } else {
                    htmlText = htmlText.replace("{{getMeritPayNum}}", String.valueOf(currentRow) + ".3");
                    dzfee = dzfee + "+" + currentRow + ".3" + getYearMonth(jsonObject, 0) + "绩效工资";
                }
            } else {
                htmlText = htmlText.replace("dzgz_merit_hiddenBox'", "' style='display:none'");

            }
            // 计费标签总计
            // 店长工资-计费过程
            htmlText = htmlText.replace("{{getDzFee}}", dzfee);

        } else {
            htmlText = htmlText.replace("dzgz_hiddenBox'", "dzgz_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("dzgz_hiddenBox1'", "dzgz_hiddenBox1' style='display:none'");
            htmlText = htmlText.replace("dzgz_hiddenBox2'", "dzgz_hiddenBox2' style='display:none'");
            htmlText = htmlText.replace("dzgz_adjust_hiddenBox'", "dzgz_adjust_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("dzgz_merit_hiddenBox'", "dzgz_merit_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("{{getDzFee}}", "0.00");
            htmlText = htmlText.replace("{{dzgz_rownumber}}.1", "-");
            htmlText = htmlText.replace("{{dzgz_rownumber}}.2", "-");
            htmlText = htmlText.replace("{{dzgz_rownumber}}.3", "-");
            htmlText = htmlText.replace("{{dzgz_rownumber}}", "-");
            htmlText = htmlText.replace("{{getMeritPayNum}}", "-");

        }
        // 12 营销经理
        if (getYxIsDisplay(jsonObject)) {

            htmlText = htmlText.replace("yxjl_hiddenBox", "");
            htmlText = htmlText.replace("yxjl_hiddenBox1", "");
            htmlText = htmlText.replace("yxjl_hiddenBox2", "");
            currentRow += 1;
            htmlText = htmlText.replace("{{yxjl_rownumber}}", String.valueOf(currentRow));
            String ysfee = "";
            ysfee = ysfee + currentRow + ".1 " + getYearMonth(jsonObject, 1) + "基本工资+" + currentRow + ".2 "
                + getYearMonth(jsonObject, 0) + "实际基本工资";
            // 季度调整序号
            boolean isAdjust = false;
            if (Convert.toBigDecimal(jsonObject.getString("38"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
                isAdjust = true;
                htmlText = htmlText.replace("yxjl_adjust_hiddenBox", "");
                ysfee = ysfee + '+' + currentRow + ".3季度调整工资";
            } else {
                htmlText = htmlText.replace("yxjl_adjust_hiddenBox'", "yxjl_adjust_hiddenBox' style='display:none'");

            }
            // 绩效序号
            if (Convert.toBigDecimal(jsonObject.getString("YSJixiaoYX"), BigDecimal.ZERO)
                .compareTo(BigDecimal.ZERO) != 0
                || Convert.toBigDecimal(jsonObject.getString("36"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
                htmlText = htmlText.replace("yxjl_merit_hiddenBox", "");
                if (isAdjust) {
                    htmlText = htmlText.replace("{{getYxMeritPayNum}}", String.valueOf(currentRow) + ".4");
                    ysfee = ysfee + "+" + currentRow + ".4" + getYearMonth(jsonObject, 0) + "绩效工资";
                } else {
                    htmlText = htmlText.replace("{{getYxMeritPayNum}}", String.valueOf(currentRow) + ".3");
                    ysfee = ysfee + "+" + currentRow + ".3" + getYearMonth(jsonObject, 0) + "绩效工资";
                }
            } else {
                htmlText = htmlText.replace("yxjl_merit_hiddenBox'", "' style='display:none'");

            }
            // 计费标签总计
            // 营销经理-计费过程总计
            htmlText = htmlText.replace("{{getYxFeeProcess}}", ysfee);
        } else {
            htmlText = htmlText.replace("yxjl_hiddenBox'", "yxjl_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("yxjl_hiddenBox1'", "yxjl_hiddenBox1' style='display:none'");
            htmlText = htmlText.replace("yxjl_hiddenBox2'", "yxjl_hiddenBox2' style='display:none'");
            htmlText = htmlText.replace("yxjl_adjust_hiddenBox'", "yxjl_adjust_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("yxjl_merit_hiddenBox'", "yxjl_merit_hiddenBox' style='display:none'");
            htmlText = htmlText.replace("{{yxjl_rownumber}}.1", "-");
            htmlText = htmlText.replace("{{yxjl_rownumber}}.2", "-");
            htmlText = htmlText.replace("{{yxjl_rownumber}}.3", "-");
            htmlText = htmlText.replace("{{yxjl_rownumber}}", "-");
            htmlText = htmlText.replace("{{getYxMeritPayNum}}", "-");

        }
         //校验总金额、本期应付总金额、各项总计
        BigDecimal oneCompany = Convert.toBigDecimal(getAccountOneAmount(jsonObject), BigDecimal.ZERO);
        BigDecimal twoCompany = Convert.toBigDecimal(getTotalTwoFee(jsonObject, 3), BigDecimal.ZERO);
        if (displayTip(jsonObject)) {
            twoCompany = BigDecimal.ZERO;
        }
        BigDecimal threeCompany = Convert.toBigDecimal(getDzTotalMoney(jsonObject, 0), BigDecimal.ZERO);
        if (threeCompany.compareTo(BigDecimal.ZERO) < 0) {
            threeCompany = BigDecimal.ZERO;
        }
        BigDecimal fourCompany = Convert.toBigDecimal(getYxSalary(jsonObject, 1), BigDecimal.ZERO);
        if (!getIsDiffCompany(jsonObject) || fourCompany.compareTo(BigDecimal.ZERO) < 0) {
            fourCompany = BigDecimal.ZERO;
        }
        BigDecimal totalCompany = oneCompany.add(twoCompany).add(threeCompany).add(fourCompany);
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("checked", 0);

        if (mayPayMoney.compareTo(totalCompany) == 0) {
            resultMap.put("checked", 1);
        }
        logger.info("本期应付金额mayPayMoney=>" + jsonObject.getString("ShopID") + "==" + mayPayMoney + "==" + totalCompany
            + "==checked=" + resultMap.get("checked"));

        logger.info("INFO=>htmlText=>{}",htmlText);
        resultMap.put("htmlText", htmlText);

        return resultMap;
    }

    private String getDzDebtTip(JSONObject jsonObject, BigDecimal fee) {
        // BigDecimal gongziNum = Convert.toBigDecimal(jsonObject.getString("gongziNum"), BigDecimal.ZERO).setScale(2,
        // RoundingMode.HALF_UP);
        if (fee.compareTo(BigDecimal.ZERO) < 0) {
            return "余" + fee.abs().setScale(2, RoundingMode.HALF_UP).toString();
        }
        return fee.setScale(2, RoundingMode.HALF_UP).toString();
    }

    public String getYxDebtTip(JSONObject jsonObject, BigDecimal fee) {
        BigDecimal gongziNum = Convert.toBigDecimal(jsonObject.getString("yingxiaoGzNum"), BigDecimal.ZERO).setScale(2,
            RoundingMode.HALF_UP);
        if (getIsDiffCompany(jsonObject) && gongziNum.compareTo(BigDecimal.ZERO) == 0
            && fee.compareTo(BigDecimal.ZERO) <= 0) {
            return "0.00";
        }
        return fee.setScale(2, RoundingMode.HALF_UP).toString();
    }

    /**
     * @Description: 营销经理开票总金额
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-10-12
     */
    // private String getYxTotalMoney(JSONObject jsonObject) {
    // }

    /**
     * @Description: 营销经理账务公司序号
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-10-12
     */
    public String getFourAccountNumber(JSONObject jsonObject) {
        if (getDzDisplay(jsonObject)) {
            return "四、";
        }
        return "三、";
    }

    public boolean getIsDiffCompany(JSONObject jsonObject) {

        return !Convert.toStr(jsonObject.getString("AccountInfo2"), "")
            .equals(Convert.toStr(jsonObject.getString("AccountInfo3")));
    }

    /**
     * @Description: 是否显示店长
     * @Param: []
     * @return: boolean
     * @Author: tf
     * @Date: 2024-10-08
     */
    public boolean getDzDisplay(JSONObject jsonObject) {
        String company = Convert.toStr(jsonObject.getString("AccountInfo2"), "");

        if ("青岛狮子智能科技有限公司".equals(company)) {
            return false;
        }
        if (Convert.toBigDecimal(jsonObject.getString("gongziNum"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YSGongZi"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("YSGongZi"), jsonObject.getString("19"), 19, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("28"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YSJixiao"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("YSJixiao"), jsonObject.getString("16"), 16, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @Description: 是否显示营业经理
     * @Param: []
     * @return: boolean
     * @Author: tf
     * @Date: 2024-09-30
     */
    private boolean getYxIsDisplay(JSONObject jsonObject) {
        if (Convert.toBigDecimal(jsonObject.getString("yingxiaoGzNum"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YSGongZiYX"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("YSGongZiYX"), jsonObject.getString("39"), 39, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("38"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YSJixiaoYX"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("YSJixiaoYX"), jsonObject.getString("36"), 36, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @Description: 劳务公司总费用
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getDzTotalMoney(JSONObject jsonObject, Integer type) {
        // 店长
        BigDecimal totalMoney = BigDecimal.ZERO;
        if (getDzDisplay(jsonObject)) {
            String shopManagerFee = getShopManagerSalaryShouldPay(jsonObject,1);
            if(!getYxIsDisplay(jsonObject)){

                return shopManagerFee;
            }
            totalMoney = totalMoney.add(Convert.toBigDecimal(shopManagerFee, BigDecimal.ZERO));
        }
        // 营销经理
        if (!getIsDiffCompany(jsonObject)) {
            String yxManagerFee = getYxSalary(jsonObject, 1);
            totalMoney = totalMoney.add(Convert.toBigDecimal(yxManagerFee, BigDecimal.ZERO));

        }
        if (1 == type && totalMoney.compareTo(BigDecimal.ZERO) < 0) {
            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString();
        }
        if (totalMoney.compareTo(BigDecimal.ZERO) < 0) {
            return "余" + totalMoney.abs().setScale(2, RoundingMode.HALF_UP).toString();
        }
        return totalMoney.setScale(2, RoundingMode.HALF_UP).toString();
    }

    /**
     * @Description: 营销经理计算标准总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getYxFeeProcess(JSONObject jsonObject) {
        // 基本工资
        String ysfee = "";
        ysfee = ysfee + 12 + ".1 " + getYearMonth(jsonObject, 1) + "基本工资+" + 12 + ".2 " + getYearMonth(jsonObject, 0)
            + "实际基本工资";
        BigDecimal amount38 = Convert.toBigDecimal(jsonObject.getString("38"), BigDecimal.ZERO);
        BigDecimal yxJixiaoYX = Convert.toBigDecimal(jsonObject.getString("YSJixiaoYX"), BigDecimal.ZERO);
        if (amount38.compareTo(BigDecimal.ZERO) != 0) {
            ysfee = ysfee + '+' + 12 + ".3季度调整工资";
        }

        // 绩效工资序号
        if (amount38.compareTo(BigDecimal.ZERO) != 0 && (yxJixiaoYX.compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(calcShouldPay(jsonObject.getString("YSJixiaoYX"), jsonObject.getString("36"), 36, jsonObject))
            .compareTo(BigDecimal.ZERO) != 0)) {
            ysfee = ysfee + "+" + 12 + ".4" + getYearMonth(jsonObject, 0) + "绩效工资";
        }

        if (amount38.compareTo(BigDecimal.ZERO) == 0 && (yxJixiaoYX.compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(calcShouldPay(jsonObject.getString("YSJixiaoYX"), jsonObject.getString("36"), 36, jsonObject))
            .compareTo(BigDecimal.ZERO) != 0)) {
            ysfee = ysfee + "+" + 12 + ".3" + getYearMonth(jsonObject, 0) + "绩效工资";
        }

        return ysfee;
    }

    /**
     * @Description: 营销经理-本期应付总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getYxSalary(JSONObject jsonObject, Integer type) {
        BigDecimal yingxiaoGzNum = Convert.toBigDecimal(jsonObject.getString("yingxiaoGzNum"), BigDecimal.ZERO);
        BigDecimal yxGongZiYX = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSGongZiYX"), jsonObject.getString("39"), 39, jsonObject));
        BigDecimal amount38 = Convert.toBigDecimal(jsonObject.getString("38"), BigDecimal.ZERO);
        BigDecimal yxJixiaoYX = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSJixiaoYX"), jsonObject.getString("36"), 36, jsonObject));
        //
        // if( yingxiaoGzNum.compareTo(BigDecimal.ZERO)<=0){
        // BigDecimal baseAmount = BigDecimal.ZERO;
        // if(yingxiaoGzNum.compareTo(BigDecimal.ZERO)>0){
        // baseAmount = baseAmount.add(yingxiaoGzNum);
        // }
        // if(yxGongZiYX.compareTo(BigDecimal.ZERO)>0){
        // baseAmount = baseAmount.add(yxGongZiYX);
        // }
        // if(amount38.compareTo(BigDecimal.ZERO)>0){
        // baseAmount = baseAmount.add(amount38);
        // }
        // if(yxJixiaoYX.compareTo(BigDecimal.ZERO)>0){
        // baseAmount = baseAmount.add(yxJixiaoYX);
        // }
        // return a.setScale(2,RoundingMode.HALF_UP).toString();

        // }
        BigDecimal yxgz = yingxiaoGzNum.add(yxGongZiYX).add(amount38).add(yxJixiaoYX);
        if (type == 1 && yxgz.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString();
        }
        if (type == 0 && yxgz.compareTo(BigDecimal.ZERO) <= 0) {
            return "余" + yxgz.abs().setScale(2, RoundingMode.HALF_UP).toString();
        }

        return yxgz.setScale(2, RoundingMode.HALF_UP).toString();

    }

    /**
     * @Description: 营销经理前期欠款总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getYxPreBalance(JSONObject jsonObject) {
        return Convert.toBigDecimal(jsonObject.getString("YSJixiaoYX"), BigDecimal.ZERO)
            .add(Convert.toBigDecimal(jsonObject.getString("YSGongZiYX"), BigDecimal.ZERO))
            .setScale(2, RoundingMode.HALF_UP).toString();
    }

    /**
     * @Description: 营销经理-本期费用总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getYxCurrentAmount(JSONObject jsonObject) {
        return Convert.toBigDecimal(jsonObject.getString("36"), BigDecimal.ZERO)
            .add(Convert.toBigDecimal(jsonObject.getString("yingxiaoGzNum"), BigDecimal.ZERO))
            .add(Convert.toBigDecimal(jsonObject.getString("38"))).add(Convert.toBigDecimal(jsonObject.getString("39")))
            .setScale(2, RoundingMode.HALF_UP).toString();

    }

    /**
     * @Description: 店长工资-计费过程总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getDzFeeProcess(JSONObject jsonObject) {
        String dzfee = "";
        dzfee = dzfee + 11 + ".1 " + getYearMonth(jsonObject, 1) + "基本工资+" + 11 + ".2 " + getYearMonth(jsonObject, 0)
            + "实际基本工资";
        BigDecimal amount28 = Convert.toBigDecimal(jsonObject.getString("28"), BigDecimal.ZERO);
        BigDecimal ysJixiaoYX = Convert.toBigDecimal(jsonObject.getString("YSJixiaoYX"), BigDecimal.ZERO);
        BigDecimal amount16 = Convert.toBigDecimal(jsonObject.getString("16"), BigDecimal.ZERO);

        if (amount28.compareTo(BigDecimal.ZERO) != 0) {
            dzfee = dzfee + '+' + 11 + ".3季度调整工资";
        }
        // 绩效工资序号
        if (amount28.compareTo(BigDecimal.ZERO) != 0 && (ysJixiaoYX.compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(calcShouldPay(jsonObject.getString("YSJixiao"), amount16.toString(), 16, jsonObject),
                BigDecimal.ZERO)
            .compareTo(BigDecimal.ZERO) != 0)) {
            dzfee = dzfee + "+" + 11 + ".4" + getYearMonth(jsonObject, 0) + "绩效工资";
        }
        if (amount28.compareTo(BigDecimal.ZERO) == 0 && (ysJixiaoYX.compareTo(BigDecimal.ZERO) != 0 || Convert
            .toBigDecimal(calcShouldPay(jsonObject.getString("YSJixiao"), amount16.toString(), 16, jsonObject),
                BigDecimal.ZERO)
            .compareTo(BigDecimal.ZERO) != 0)) {
            dzfee = dzfee + "+" + "11" + ".3" + getYearMonth(jsonObject, 0) + "绩效工资";
        }
        return dzfee;
    }

    /**
     * @Description: 店长工资-应发工资
     * @Param: [jsonObject] displayType:0-显示金额，1-显示余
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */

    private String getShopManagerSalaryShouldPay(JSONObject jsonObject,Integer displayType) {

        BigDecimal gongZi = Convert.toBigDecimal(jsonObject.getString("gongziNum"), BigDecimal.ZERO);
        BigDecimal YsGongZi = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSGongZi"), jsonObject.getString("19"), 19, jsonObject),
            BigDecimal.ZERO);
        BigDecimal amount28 = Convert.toBigDecimal(jsonObject.getString("28"), BigDecimal.ZERO);
        BigDecimal YSJixiao = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSJixiao"), jsonObject.getString("16"), 16, jsonObject),
            BigDecimal.ZERO);
        // if(getIsDiffCompany(jsonObject) && gongZi.compareTo(BigDecimal.ZERO)<=0){
        // BigDecimal amount = BigDecimal.ZERO;
        // if(YsGongZi.compareTo(BigDecimal.ZERO)>0){
        // amount = amount.add(YsGongZi);
        // }
        // if(amount28.compareTo(BigDecimal.ZERO)>0){
        // amount = amount.add(amount28);
        // }
        // if(YSJixiao.compareTo(BigDecimal.ZERO)>0){
        // amount = amount.add(YSJixiao);
        // }
        // return amount.setScale(2, RoundingMode.HALF_UP).toString();
        // }
        BigDecimal dzSalary = gongZi.add(YsGongZi).add(amount28).add(YSJixiao).setScale(2, RoundingMode.HALF_UP);
        //本期应付小于0则加余不参与合计
        // String shopManagerSalary = getShopManagerSalary(jsonObject);
        // BigDecimal  shopManagerSalaryDecimal = Convert.toBigDecimal(shopManagerSalary,BigDecimal.ZERO);
        if(dzSalary.compareTo(BigDecimal.ZERO) <0 && displayType == 1) {
            return "余" + dzSalary.abs().setScale(2, RoundingMode.HALF_UP).toString();
        }

        // if (dzSalary.compareTo(BigDecimal.ZERO) <= 0) {
        // return "余" + dzSalary.abs().setScale(2, RoundingMode.HALF_UP).toString();
        // }
        return dzSalary.setScale(2, RoundingMode.HALF_UP).toString();
    }

    /**
     * @Description: 店长工资-前期欠款
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String shopManagerBalance(JSONObject jsonObject) {
        BigDecimal gongZi = Convert.toBigDecimal(jsonObject.getString("YSGongZi"), BigDecimal.ZERO);
        BigDecimal jixiao = Convert.toBigDecimal(jsonObject.getString("YSJixiao"), BigDecimal.ZERO);
        return gongZi.add(jixiao).setScale(2, RoundingMode.HALF_UP).toString();
    }
    /**
    * @Description: 本期费用
    * @Param: [jsonObject]
    * @return: java.lang.String
    * @Author: tf
    * @Date: 2024-11-07
    */
    private String getShopManagerSalary(JSONObject jsonObject) {
        BigDecimal salary = Convert.toBigDecimal(jsonObject.getString("gongziNum"), BigDecimal.ZERO);
        BigDecimal account_19 = Convert.toBigDecimal(jsonObject.getString("19"), BigDecimal.ZERO);
        BigDecimal account_28 = Convert.toBigDecimal(jsonObject.getString("28"), BigDecimal.ZERO);
        BigDecimal account_16 = Convert.toBigDecimal(jsonObject.getString("16"), BigDecimal.ZERO);

        return salary.add(account_16).add(account_19).add(account_28).setScale(2, RoundingMode.HALF_UP).toString();
    }

    /**
     * @Description: 年月格式化
     * @Param: [jsonObject, type]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-30
     */
    private String getYearMonth(JSONObject jsonObject, Integer type) {

        try {
            DateTime atimeDateTime = DateUtil.parse(jsonObject.getString("Atime"));
            if (type.equals(1)) {
                atimeDateTime = DateUtil.offsetMonth(atimeDateTime, 1);
            }
            String atime = DateUtil.format(atimeDateTime, "yyyy年MM月");
            return atime;
        } catch (Exception e) {
            logger.error("日期转换失败，date:{}", jsonObject.getString("Atime"), e);
        }
        return "";
    }

    private String formatYm(String dateATime) {

        try {
            DateTime atimeDateTime = DateUtil.parse(dateATime);
            String atime = DateUtil.format(atimeDateTime, "yyyy-MM");
            return atime;
        } catch (Exception e) {
            logger.error("日期转换失败，date:{}", dateATime, e);
        }
        return "";
    }

    /**
     * @Description: 公司2总计
     * @Param: [jsonObject]
     * @return: java.lang.CharSequence
     * @Author: tf
     * @Date: 2024-09-29
     */

    private String getTotalTwoFee(JSONObject jsonObject, Integer type) {
        // ai系统维护费
        BigDecimal aiAmount = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSsystemFee"), jsonObject.getString("08"), 8, jsonObject),
            BigDecimal.ZERO);
        // 客源输送费本期应付总计
        BigDecimal transportAmount = Convert.toBigDecimal(getTransportShouldPay(jsonObject), BigDecimal.ZERO);
        // 会员管理费
        BigDecimal memberAmount = Convert.toBigDecimal(getMemberShouldPay(jsonObject), BigDecimal.ZERO);
        BigDecimal totalShouldPay = aiAmount.add(transportAmount).add(memberAmount).setScale(2, RoundingMode.HALF_UP);
        // 非专项抵扣，本期应应付大于0，总计小于0则显示余
        if (!Convert.toBool(jsonObject.getString("slitfee"))) {
            if (displayTip(jsonObject) && 1 == type) {
                logger.info("totalShouldPay==>{}", totalShouldPay);
                return totalShouldPay.compareTo(BigDecimal.ZERO) < 0 ? "余" + totalShouldPay.abs()
                    : totalShouldPay.toString();
            }
            if (type == 2) {
                return totalShouldPay.compareTo(BigDecimal.ZERO) < 0 ? "0.00" : totalShouldPay.toString();
            }

        }
        if (displayTip(jsonObject)) {
            totalShouldPay = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        }
        return totalShouldPay.toString();

    }

    public Boolean displayTip(JSONObject jsonObject) {
        BigDecimal account8 = Convert.toBigDecimal(jsonObject.getString("08"), BigDecimal.ZERO);
        // BigDecimal account31 = Convert.toBigDecimal(jsonObject.getString("31"), BigDecimal.ZERO);
        BigDecimal account6 = Convert.toBigDecimal(jsonObject.getString("06"), BigDecimal.ZERO);
        BigDecimal account29 = Convert.toBigDecimal(jsonObject.getString("29"), BigDecimal.ZERO);
        BigDecimal account23 = Convert.toBigDecimal(jsonObject.getString("23"), BigDecimal.ZERO);
        BigDecimal account4 = Convert.toBigDecimal(jsonObject.getString("04"), BigDecimal.ZERO);
        BigDecimal account22 = Convert.toBigDecimal(jsonObject.getString("22"), BigDecimal.ZERO);
        BigDecimal account30 = Convert.toBigDecimal(jsonObject.getString("30"), BigDecimal.ZERO);
        BigDecimal totalAmount = account8.add(account6).add(account29).add(account23).add(account4)
            .add(account22).add(account30);
        // 前期欠款
        BigDecimal ySsystemFee = Convert.toBigDecimal(jsonObject.getString("YSsystemFee"), BigDecimal.ZERO);
        BigDecimal ySbookfee = Convert.toBigDecimal(jsonObject.getString("YSbookfee"), BigDecimal.ZERO);
        BigDecimal ysBookJM = Convert.toBigDecimal(jsonObject.getString("ysBookJM"), BigDecimal.ZERO);
        BigDecimal ysyjjmfee = Convert.toBigDecimal(jsonObject.getString("ysyjjmfee"), BigDecimal.ZERO);
        BigDecimal ySjifen = Convert.toBigDecimal(jsonObject.getString("YSjifen"), BigDecimal.ZERO);
        BigDecimal jFDX3 = Convert.toBigDecimal(jsonObject.getString("JFDX3"), BigDecimal.ZERO);
        BigDecimal ysIntegralJM = Convert.toBigDecimal(jsonObject.getString("ysIntegralJM"), BigDecimal.ZERO);
        BigDecimal debtAmount =
            ySsystemFee.add(ySbookfee).add(ysBookJM).add(ysyjjmfee).add(ySjifen).add(jFDX3).add(ysIntegralJM);
        // 当期费小于0 前期有结余 是负数
        // 当前费用小于0 前期有欠款 相减小于0 是负数 大于0是应缴
        // 当前费用大于0 前期欠款有结余 相减小于0 则是余
        // 当前费用大于0 前期有欠款 相减 直接显示
        if (totalAmount.compareTo(BigDecimal.ZERO) >= 0
            && totalAmount.subtract(debtAmount).compareTo(BigDecimal.ZERO) < 0) {
            return true;

        }
        return false;
    }

    /**
     * @Description: 会员管理计费标签总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-29
     */
    private String getMemberStandard(JSONObject jsonObject, Integer number) {
        String hyglfee = "";
        hyglfee = hyglfee + number + ".1积分管理费+" + number + ".2积分抵现金额";

        // let memberDiscount = parseFloat(shopInfo.ysIntegralJM)<0?parseFloat(shopInfo.ysIntegralJM)+parseFloat
        // (shopInfo['30']):parseFloat(shopInfo['30'])
        if (Convert.toBigDecimal(jsonObject.getString("ysIntegralJM"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("ysIntegralJM"), jsonObject.getString("30"), 30, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            hyglfee = hyglfee + '+' + number + ".3员管理费减免";
        }

        return hyglfee;
    }

    private String getMemberShouldPay(JSONObject jsonObject) {

        BigDecimal ysjifen = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSjifen"), jsonObject.getString("04"), 4, jsonObject), BigDecimal.ZERO);
        BigDecimal jfdx3 = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("JFDX3"), jsonObject.getString("22"), 22, jsonObject), BigDecimal.ZERO);
        BigDecimal ysIntegralJM = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("ysIntegralJM"), jsonObject.getString("30"), 30, jsonObject),
            BigDecimal.ZERO);

        return ysjifen.add(jfdx3).add(ysIntegralJM).setScale(2, RoundingMode.HALF_UP).toString();
    }

    private String getTransportFeeProcess(JSONObject jsonObject, Integer number) {
        String sskyfee = "";

        sskyfee = sskyfee + number + ".1线上订单预订佣金+" + number + ".2线下订单中央输送费金额";
        if (Convert.toBigDecimal(jsonObject.getString("ysBookJM"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("ysBookJM"), jsonObject.getString("29"), 29, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            sskyfee = sskyfee + '+' + number + ".3输送客源费减免";
        }
        if ((Convert.toBigDecimal(jsonObject.getString("ysBookJM"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("ysBookJM"), jsonObject.getString("29"), 29, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0)
            && (Convert.toBigDecimal(jsonObject.getString("ysyjjmfee"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
                || Convert
                    .toBigDecimal(
                        calcShouldPay(jsonObject.getString("ysyjjmfee"), jsonObject.getString("23"), 23, jsonObject))
                    .compareTo(BigDecimal.ZERO) != 0)) {
            sskyfee = sskyfee + '+' + number + ".4售卡佣金返还";
        }
        if (Convert.toBigDecimal(jsonObject.getString("ysBookJM"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) == 0
            && Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("ysBookJM"), jsonObject.getString("29"), 29, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) == 0
            && (Convert.toBigDecimal(jsonObject.getString("ysyjjmfee"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
                || Convert
                    .toBigDecimal(
                        calcShouldPay(jsonObject.getString("ysyjjmfee"), jsonObject.getString("23"), 23, jsonObject))
                    .compareTo(BigDecimal.ZERO) != 0)) {
            sskyfee = sskyfee + '+' + number + ".3售卡佣金返还";
        }
        return sskyfee;

    }

    /**
     * @Description: 客源输送费本期应付总计
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-29
     */

    private String getTransportShouldPay(JSONObject jsonObject) {
        BigDecimal ysBookJM = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("ysBookJM"), jsonObject.getString("29"), 29, jsonObject),
            BigDecimal.ZERO);
        BigDecimal ysbookfee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSbookfee"), jsonObject.getString("06"), 6, jsonObject),
            BigDecimal.ZERO);
        BigDecimal ysyjjfee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("ysyjjmfee"), jsonObject.getString("23"), 23, jsonObject),
            BigDecimal.ZERO);
        return ysBookJM.add(ysbookfee).add(ysyjjfee).setScale(2, RoundingMode.HALF_UP).toString();

    }

    /**
     * @param oldValue
     * @param newValue
     * @param tip
     * @return
     * @desc 计费标准-字符串替换
     */
    public String replaceStr(String oldValue, String newValue, String tip) {
        System.out.println("old=>" + oldValue + "=new=>" + newValue + "=tip=>" + tip);

        if (StringUtils.isNotBlank(oldValue) && oldValue.contains("营业收入")) {
            return tip + oldValue.replace("营业收入", newValue);
        } else if (StringUtils.isNotBlank(oldValue) && oldValue.contains("积分数")) {
            return tip + oldValue.replace("积分数", newValue);
        } else if (StringUtils.isNotBlank(oldValue) && oldValue.indexOf("预订金额") >= 0) {
            return tip + oldValue.replace("预订金额", newValue);
        } else if (StringUtils.isNotBlank(oldValue) && oldValue.contains("积分数")) {
            return tip + oldValue.replace("积分数", newValue);
        } else {
            return Convert.toStr(oldValue, "");
        }

    }

    public String replaceOrderStr(String oldValue, String newValue, String tip) {
        if (StringUtils.isNotBlank(oldValue) && oldValue.contains("预订金额")) {
            // old = tip+String(old).replace('预订金额', newStr);
            return tip + oldValue.replace("预订金额", newValue);

        } else if (StringUtils.isNotBlank(oldValue) && oldValue.contains("*订单金额")) {
            // old = tip+newStr+'*'+String(old).replace('*订单金额', '');

            return tip + newValue + "*" + oldValue.replace("*订单金额", "");

        } else {
            return Convert.toStr(oldValue, "");
        }

    }

    /**
     * @Description: 前期余额提示大于0则应付少于0则显示余
     * @Param: [fee]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-23
     */
    public String balanceTip(String fee) {
        BigDecimal balance = Convert.toBigDecimal(fee, BigDecimal.ZERO);
        if (balance.compareTo(BigDecimal.ZERO) < 0) {
            return Math.abs(balance.setScale(2, RoundingMode.HALF_UP).doubleValue()) + "";
        } else if (balance.compareTo(BigDecimal.ZERO) > 0) {
            return "余" + balance.setScale(2, RoundingMode.HALF_UP);
        } else {
            return balance.setScale(2, RoundingMode.HALF_UP).toString();
        }
    }

    /**
     * @Description: 前期余额小于0则应收金额相加
     * @Param: [balance, amount]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-23
     */
    public String calcShouldPay(String debt, String balance, Integer type, JSONObject jsonObject) {

        // 调整计算
        BigDecimal balanceBigDecimal = Convert.toBigDecimal(balance, BigDecimal.ZERO);
        BigDecimal debtBigDecimal = Convert.toBigDecimal(debt, BigDecimal.ZERO);
        if (Arrays.asList(8, 31, 6, 29, 23, 4, 22, 30).contains(type)
            && Convert.toBool(jsonObject.getBoolean("slitfee"), Boolean.FALSE)) {
            // 分项抵扣-费用项只可抵消当前费用，前期欠款大于0，则正常相加，前期欠款小于0，应付金额则显示0(sql 有结余是大于0，有欠款是<0)
            BigDecimal slitFeeAmount = BigDecimal.ZERO;
            if (balanceBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
                if (debtBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
                    slitFeeAmount = balanceBigDecimal.subtract(debtBigDecimal);
                } else {
                    slitFeeAmount = balanceBigDecimal.add(debtBigDecimal);
                }

            } else {
                if (balanceBigDecimal.subtract(debtBigDecimal).compareTo(BigDecimal.ZERO) < 0) {
                    slitFeeAmount = BigDecimal.ZERO;
                } else {
                    slitFeeAmount = balanceBigDecimal.subtract(debtBigDecimal);
                }
            }
            return slitFeeAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString();

        } else if (Arrays.asList(8, 31, 6, 29, 23, 4, 22, 30).contains(type)) {
            // 非分项抵扣，总计本期费用大于0，在本期应付总计小于0则加余，本期费用小于0，前期欠款小于0，不参与计算，大于0则正常计算
            BigDecimal account8 = Convert.toBigDecimal(jsonObject.getString("08"), BigDecimal.ZERO);
            // BigDecimal account31 = Convert.toBigDecimal(jsonObject.getString("31"), BigDecimal.ZERO);
            BigDecimal account6 = Convert.toBigDecimal(jsonObject.getString("06"), BigDecimal.ZERO);
            BigDecimal account29 = Convert.toBigDecimal(jsonObject.getString("29"), BigDecimal.ZERO);
            BigDecimal account23 = Convert.toBigDecimal(jsonObject.getString("23"), BigDecimal.ZERO);
            BigDecimal account4 = Convert.toBigDecimal(jsonObject.getString("04"), BigDecimal.ZERO);
            BigDecimal account22 = Convert.toBigDecimal(jsonObject.getString("22"), BigDecimal.ZERO);
            BigDecimal account30 = Convert.toBigDecimal(jsonObject.getString("30"), BigDecimal.ZERO);
            BigDecimal totalAmount = account8.add(account6).add(account29).add(account23).add(account4)
                .add(account22).add(account30);

            //本期费用小于0 前期欠款有结余
            if (totalAmount.compareTo(BigDecimal.ZERO) < 0) {
                if (debtBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
                    return balanceBigDecimal.subtract(debtBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).toString();

                } else {
                    // return balanceBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                    return   balanceBigDecimal.subtract(debtBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                }
            } else {
                return balanceBigDecimal.subtract(debtBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).toString();

            }
        }

        // 结束调整

        /*   if (Arrays.asList(2, 7, 18, 20, 21, 26, 27).contains(Convert.toInt(type))) {
        
            if (balanceBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
                if (debtBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
                    return balanceBigDecimal.subtract(debtBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP)
                        .toString();
                } else {
                    return balanceBigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                }
            } else {
                if (balanceBigDecimal.subtract(debtBigDecimal).compareTo(BigDecimal.ZERO) < 0) {
                    return "0.00";
                } else {
                    return balanceBigDecimal.subtract(debtBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP)
                        .toString();
                }
            }
        
        }*/
        //抵销预收金额是0 则账务公司一费用应付金额为为负时显示0
        BigDecimal decYS = Convert.toBigDecimal(jsonObject.getString("decYS"),BigDecimal.ZERO);
        BigDecimal decYSGZ = Convert.toBigDecimal(jsonObject.getString("decYSGZ"),BigDecimal.ZERO);
        BigDecimal decYSSZ =decYS.add(decYSGZ);
        if (Arrays.asList(2, 7, 18, 20, 21, 26, 27).contains(Convert.toInt(type)) && decYSSZ.compareTo(BigDecimal.ZERO) == 0   ) {
             if(balanceBigDecimal.subtract(debtBigDecimal).compareTo(BigDecimal.ZERO)>0){
                 return balanceBigDecimal.subtract(debtBigDecimal).setScale(2, RoundingMode.HALF_UP).toString();
             }
             return "0.00";
        }
        BigDecimal resultAmount = balanceBigDecimal.subtract(debtBigDecimal)    ;
        // 运舆情使用费和运营顾问费小于0则显示0
        if (Arrays.asList(21, 26).contains(Convert.toInt(type)) && resultAmount.compareTo(BigDecimal.ZERO) < 0) {
            return "0.00";
        }
        return resultAmount.setScale(2, RoundingMode.HALF_UP).toString();

    }

    /**
     * @Description: 公司一总额计算
     * @Param: [jsonObject]
     * @return: java.lang.String
     * @Author: tf
     * @Date: 2024-09-24
     */
    public String getAccountOneAmount(JSONObject jsonObject) {
        BigDecimal amount = BigDecimal.ZERO;
        // 商标
        BigDecimal newbrandfee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSroomfee"), jsonObject.getString("02"), 2, jsonObject),
            BigDecimal.ZERO);

        // 运营质检
        BigDecimal newqualityFee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSzhijian"), jsonObject.getString("07"), 7, jsonObject),
            BigDecimal.ZERO);

        // 市场营销
        BigDecimal newMarketFee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSYingXiao"), jsonObject.getString("18"), 18, jsonObject),
            BigDecimal.ZERO);

        // 运营顾问费
        BigDecimal newAdviserFee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YYGUWen"), jsonObject.getString("21"), 21, jsonObject),
            BigDecimal.ZERO);

        // 品质督导费
        BigDecimal newQualitySupervisorFee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("YSDuDao"), jsonObject.getString("20"), 20, jsonObject),
            BigDecimal.ZERO);
        if (newQualitySupervisorFee.compareTo(BigDecimal.ZERO) < 0) {
            newQualitySupervisorFee = BigDecimal.ZERO;
        }

        // 舆情系统
        BigDecimal newSentimentFee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("ysyuqingfee"), jsonObject.getString("26"), 26, jsonObject),
            BigDecimal.ZERO);

        // 财务咨询费
        BigDecimal newFinanceFee = Convert.toBigDecimal(
            calcShouldPay(jsonObject.getString("yscaiwufee"), jsonObject.getString("27"), 27, jsonObject),
            BigDecimal.ZERO);

        // 总计
        return newbrandfee.add(newqualityFee).add(newMarketFee).add(newAdviserFee).add(newQualitySupervisorFee)
            .add(newSentimentFee).add(newFinanceFee).setScale(2, RoundingMode.HALF_UP).toString();
    }

    // public String getSskyShouldPay(JSONObject jsonObject){
    //
    // return parseFloat(calcShouldPay(props.shopInfo.ysBookJM,props.shopInfo['29']))+parseFloat(calcShouldPay
    // (props.shopInfo.YSbookfee,props.shopInfo['06']))+parseFloat(props.shopInfo['23']);
    // }
    // public String getMemberDebt(){
    //
    // let memberDebtAmount = parseFloat(props.shopInfo['YSjifen'])+parseFloat(props.shopInfo['JFDX3'])
    // +parseFloat(props.shopInfo['ysIntegralJM']);
    // console.log("memberDebtAmount",memberDebtAmount)
    // return tipAmount(memberDebtAmount)
    // }
    // public String getMemberShouldPay(){
    // return parseFloat(calcShouldPay(props.shopInfo['YSjifen'],props.shopInfo['04']))+parseFloat(calcShouldPay
    // (props.shopInfo['JFDX3'],props.shopInfo['22']))+parseFloat(calcShouldPay(props.shopInfo['ysIntegralJM'],
    // props.shopInfo['30']))
    // }
    // public String getAccountTwoShouldPay(){
    //
    // return parseFloat(calcShouldPay(props.shopInfo.YSsystemFee,props.shopInfo["08"]))+getSskyShouldPay()
    // +getMemberShouldPay()
    // }
    /**
     * @Description: 输送客源是 否显示
     * @Param: [jsonObject]
     * @return: java.lang.Boolean
     * @Author: tf
     * @Date: 2024-10-08
     */
    public Boolean getSskyIsDisplay(JSONObject jsonObject) {
        if (Convert.toBigDecimal(jsonObject.getString("YSbookfee"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("YSbookfee"), jsonObject.getString("06"), 6, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("ysBookJM"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("ysBookJM"), jsonObject.getString("29"), 29, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("23"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("ysyjjmfee"), BigDecimal.ZERO)
                .compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        return false;

    }

    public boolean getHyglDisplay(JSONObject jsonObject) {
        if (Convert.toBigDecimal(jsonObject.getString("03"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("YSjifen"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("JFDX3"), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(jsonObject.getString("ysIntegralJM"), BigDecimal.ZERO)
                .compareTo(BigDecimal.ZERO) != 0
            || Convert
                .toBigDecimal(calcShouldPay(jsonObject.getString("YSjifen"), jsonObject.getString("04"), 4, jsonObject),
                    BigDecimal.ZERO)
                .compareTo(BigDecimal.ZERO) != 0
            || Convert
                .toBigDecimal(calcShouldPay(jsonObject.getString("JFDX3"), jsonObject.getString("22"), 22, jsonObject),
                    BigDecimal.ZERO)
                .compareTo(BigDecimal.ZERO) != 0
            || Convert.toBigDecimal(
                calcShouldPay(jsonObject.getString("ysIntegralJM"), jsonObject.getString("30"), 30, jsonObject),
                BigDecimal.ZERO).compareTo(BigDecimal.ZERO) != 0) {
            return true;
        } else {
            return false;
        }

    }

    /**
     * @Description: 导出
     * @Param: [response]
     * @return: void
     * @Author: tf
     * @Date: 2024-08-30
     */
    public void download(HttpServletResponse response, JSONObject jsonObject) throws IOException {

        JSONArray shops = jsonObject.getJSONArray("shops");
        if (null == shops || shops.isEmpty()) {
            return;
        }
        // 压缩后的ZIP文件名
        String zipFileName = DateUtils.dateTimeNow() + ".zip";
        // 压缩文件
        File tempZipFile = File.createTempFile("compressed-", ".zip");
        FileOutputStream fos = new FileOutputStream(tempZipFile.getAbsolutePath());

        ZipOutputStream zipOut = new ZipOutputStream(fos);

        for (int i = 0; i < shops.size(); i++) {

            // response.setContentType("text/html;charset=UTF-8");
            // response.setContentType(MediaType.APPLICATION_PDF_VALUE);

            // response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

            // 获取PrintWriter来写入响应体
            // PrintWriter writer = response.getWriter();
            // 写入HTML内容
            JSONObject shop = shops.getJSONObject(i);
            // 设置响应的文件名

            String fileName = shop.getString("DQ") + "_" + shop.getString("CQ") + "_【" + shop.getString("ShopID") + "】"
                + shop.getString("shopname") + "_" + formatYm(shop.getString("Atime")) + ".pdf";
            HashMap<String, Object> resultMap = buildContent(shop, 2);
            String html = resultMap.get("htmlText").toString();
            OutputStream outputStream = null;
            InputStream inputStream = null;
            BufferedInputStream bufferedInputStream = null;
            byte[] bytes = new byte[1024];

            try {
                Thread.sleep(500);
                String pdf = generatePdf(html);

                // response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,
                // "UTF-8"));
                // 以流的形式返回文件
                // response.setContentType("application/octet-stream;charset=utf-8");
                // bufferedInputStream = new BufferedInputStream(inputStream);
                // outputStream = response.getOutputStream();
                // int bi= bufferedInputStream.read(bytes);
                // while (bi != -1) {
                // outputStream.write(bytes, 0, i);
                // bi = bufferedInputStream.read(bytes);
                // }
                // file.delete();
                compressFileToZip(fileName, pdf, tempZipFile.getAbsolutePath(), String.valueOf(i), zipOut);
                // inputStream.close();
                // todo 更新下载次数
                HashMap<String, Integer> paramMap = new HashMap<>();
                paramMap.put("fsn", Convert.toInt(shop.getInteger("FSN"), 0));
                paramMap.put("type", 2);
                shopMapper.updateOperate(paramMap);
                // if(file.delete()){
                // logger.info("删除成功");
                // }else{
                // logger.info("删除失败");
                // }

            } catch (Exception ex) {
                logger.error("导出失败", ex);
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                if (bufferedInputStream != null) {
                    bufferedInputStream.close();
                }
            }
        }
        zipOut.close();
        fos.close();

        // 设置响应头信息
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + "\"");

        // 将ZIP文件内容写入响应输出流
        try {
            try (FileInputStream fis = new FileInputStream(tempZipFile);
                OutputStream os = response.getOutputStream();) {

                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                // 删除临时ZIP文件
                tempZipFile.delete();
                os.flush();
            }
        } catch (Exception e) {
            e.getMessage();
        }

    }

    public AjaxResult adapterBill(JSONObject jsonObject) {

        return AjaxResult.success();
    }

    /**
     * @Description: 查询列表
     * @Param: []
     * @return: com.ethank.common.core.domain.AjaxResult
     * @Author: tf
     * @Date: 2024-08-30
     */
    // @Cacheable(value = "shopList", key = "#clientId")
    public AjaxResult getPageList(String clientId, String atime, String userId, String emailHost, String emailSource,
        String emailPassword, Integer emailPort, String sign, Integer loginStatus) {
        logger.info("Info=getPageList=params=clientId={}=atime={}=userId={}=emailHost={}", clientId, atime, userId,
            emailHost);

        loginStatus = Convert.toInt(loginStatus, 0);
        if (loginStatus < 1) {
            if (StringUtils.isBlank(userId) || StringUtils.isBlank(emailHost) || StringUtils.isBlank(emailSource)
                || StringUtils.isBlank(emailPassword) || null == emailPort || StringUtils.isBlank(atime)
                || StringUtils.isBlank(sign)) {
                return AjaxResult.error("操作失败,请求签名参数有误");
            }
            // 校验签名
            // if (!Arrays.asList("302", "317", "319", "320", "332", "333", "336").contains(userId)) {
            Boolean checkResult = checkSign(userId, atime, emailSource, sign);
            if (!checkResult) {
                return AjaxResult.error("签名校验失败");
            }
            // }

            // 将邮箱地址缓存
            HashMap<String, Object> map = new HashMap<>();
            map.put("host", emailHost);
            map.put("emailSource", emailSource);
            // 字符串翻转
            map.put("emailPassword", new StringBuilder(emailPassword).reverse().toString());
            map.put("emailPort", emailPort);
            redisUtil.hmset(userId, map);
            redisUtil.set(clientId, userId, 60 * 60 * 24);
        }

        HashMap<String, Object> filterMap = new HashMap<String, Object>();
        filterMap.put("atime", atime);
        filterMap.put("userId", userId);
        List<Map<String, Object>> mapList = shopMapper.getPageList(filterMap);

        return AjaxResult.success(mapList);
    }

    /**
     * @Description: 检验签名
     * @Param: [userId, atime, emailSource]
     * @return: java.lang.Boolean
     * @Author: tf
     * @Date: 2024-09-09
     */
    private Boolean checkSign(String userId, String atime, String emailSource, String sign) {
        // 加密格式 token=md5(FormatDateTime('yyyymmddhhmm',Now())+userId+atime+emailSource)
        DateTime now = DateUtil.date();
        String nowStr = DateUtil.format(now, "yyyyMMddHHmm");
        try {
            String token = DigestUtils.md5DigestAsHex((nowStr + userId + atime + emailSource).getBytes("UTF-8"));
            logger.info("Info=>checkSign=nowStr+userId+atime+emailSource={}==sign={}",
                nowStr + userId + atime + emailSource, token);
            if (token.equals(sign)) {
                return true;
            }
            // 时间分钟减1
            DateTime subNow = DateUtil.offsetMinute(now, -1);
            String nowSubStr = DateUtil.format(subNow, "yyyyMMddHHmm");
            String newToken = DigestUtils.md5DigestAsHex((nowSubStr + userId + atime + emailSource).getBytes());
            logger.info("Info=>sub=checkSign=nowStr+userId+atime+emailSource={}=sign={}",
                nowSubStr + userId + atime + emailSource, newToken);
            if (newToken.equals(sign)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }

    public SseEmitter buildConnect(String clientId) {
        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
        emitters.put(clientId, emitter);
        emitter.onCompletion(() -> emitters.remove(clientId));
        emitter.onError(error -> emitters.remove(clientId));
        // 使用线程池异步发送SSE事件 每秒发送一次SSE事件
        // scheduledExecutorService.scheduleAtFixedRate(() -> {
        // try {
        // // 发送一个SSE事件到客户端
        // emitter.send(SseEmitter.event()
        // .data("") // 设置事件数据
        // .comment("This is a comment") //注释
        // .id("") // 设置事件ID（可选）
        // .name("clientId")
        //
        // );
        // } catch (IOException e) {
        // // 如果发送失败，通常意味着连接已关闭，我们关闭发射器并停止计划任务
        // emitter.completeWithError(e);
        // scheduledExecutorService.shutdown();
        // }
        // }, 0, 1, TimeUnit.SECONDS);
        //
        // // 当连接关闭时，确保关闭发射器和线程池
        // emitter.onCompletion(() -> scheduledExecutorService.shutdown());
        // emitter.onError((e) -> {
        // scheduledExecutorService.shutdown();
        // emitter.completeWithError(e);
        // });
        // emitter.onTimeout(() -> {
        // scheduledExecutorService.shutdown();
        // emitter.completeWithError(new RuntimeException("SSE Timeout"));
        // });
        return emitter;

    }

    /**
     * @Description: 发送消息到前端
     * @Param: [clientId, data]
     * @return: void
     * @Author: tf
     * @Date: 2024-09-05
     */

    public void sendUpdateToClient(String clientId, String data) {
        SseEmitter emitter = emitters.get(clientId);
        logger.info("Info=sendUpdateToClient=params=emitter={}=clientId={}=data={}", emitter, clientId, data);

        if (emitter != null) {
            try {
                emitter.send(SseEmitter.event().reconnectTime(1000).data(data));
                // emitter.send(data);
            } catch (IOException e) {
                emitters.remove(clientId);
            }
        }
    }

    /**
     * @Description: 中止邮件发送
     * @Param: [clientId]
     * @return: com.ethank.common.core.domain.AjaxResult
     * @Author: tf
     * @Date: 2024-08-30
     */
    public AjaxResult stopSendEmail(String clientId) {
        isCancel.set(true);
        // sendUpdateToClient(clientId, mailMsg.toString());
        return AjaxResult.success();
    }

    /**
     * 生成 pdf 文件
     */
    private String generatePdf(String path) throws Exception {
        String pdfDirPath = PATH + File.separator + "pdf" + File.separator;
        File file = new File(pdfDirPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        String pdfPath = pdfDirPath + UUID.fastUUID().toString(true) + ".pdf";
        // ClassPathResource classPathResource = new ClassPathResource(path);
        // InputStream inputStream = classPathResource.getInputStream();
        InputStream inputStream = new ByteArrayInputStream(path.getBytes(StandardCharsets.UTF_8));
        OutputStream outputStream = new FileOutputStream(pdfPath);
        HtmlToPdfUtils.convertToPdf(inputStream, outputStream);
        return pdfPath;
    }

    public AjaxResult getOnlineList(String shopId, String atime) {
        if (StringUtils.isBlank(shopId) || StringUtils.isBlank(atime)) {
            return AjaxResult.error("请求参数有误");
        }
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("shopId", shopId);
        paramMap.put("atime", atime);
        List<Map<String, Object>> result = shopMapper.getPageOnlineList(paramMap);

        return AjaxResult.success(result);
    }

    public AjaxResult getOfflineList(String shopId, String atime) {

        if (StringUtils.isBlank(shopId) || StringUtils.isBlank(atime)) {
            return AjaxResult.error("请求参数有误");
        }
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("shopId", shopId);
        paramMap.put("atime", atime);
        List<Map<String, Object>> result = shopMapper.getOfflineList(paramMap);

        return AjaxResult.success(result);
    }

    public AjaxResult getCashBill(String shopId, String atime) {

        if (StringUtils.isBlank(shopId) || StringUtils.isBlank(atime)) {
            return AjaxResult.error("请求参数有误");
        }
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("shopId", shopId);
        paramMap.put("atime", atime);
        List<Map<String, Object>> result = shopMapper.getCashBill(paramMap);

        return AjaxResult.success(result);
    }

    /**
     * @Description: 压缩文件
     * @Param: [tradeId, fileUrl, zipFilePath, index, zipOut]
     * @return: void
     * @Author: tf
     * @Date: 2024-07-10
     */
    private void compressFileToZip(String fileName, String filePath, String zipFilePath, String index,
        ZipOutputStream zipOut) {
        try {
            File file = new File(filePath);
            InputStream inputStream = new FileInputStream(file);
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOut.putNextEntry(zipEntry);

            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                zipOut.write(buffer, 0, length);
            }

            zipOut.closeEntry();
            inputStream.close();
        } catch (Exception e) {
            e.getMessage();
        }
    }

    public AjaxResult getHtmlContent(JSONObject jsonObject) {
        HashMap<String, Object> resultMap = null;
        try {

            resultMap = buildContent(jsonObject.getJSONObject("shop"), 2);
        } catch (IOException e) {
            return AjaxResult.error("请联系管理人员,执行失败");
        }
        return AjaxResult.success(resultMap);

    }

    public AjaxResult getMobileDisplayInfo(JSONObject jsonObject) {
        String shopId = Convert.toStr(jsonObject.getString("shopId"), "");
        if (StringUtils.isBlank(shopId)) {
            return AjaxResult.error("请求参数有误");
        }
        String sign = Convert.toStr(jsonObject.getString("sign"), "");

        if (StringUtils.isBlank(sign)) {
            return AjaxResult.error("请求参数有误");
        }

        DateTime now = DateUtil.date();
        String nowStr = DateUtil.format(now, "yyyyMMddHHmm");
        boolean flag = false;
        try {
            String token = DigestUtils.md5DigestAsHex((nowStr + shopId).getBytes("UTF-8"));
            logger.info("Info=>checkSign=nowStr={}==sign={}", nowStr + shopId, token);

            if (token.equals(sign)) {
                flag = true;
            }
            if (!flag) {
                // 时间分钟减1
                DateTime subNow = DateUtil.offsetMinute(now, -1);
                String nowSubStr = DateUtil.format(subNow, "yyyyMMddHHmm");
                String newToken = DigestUtils.md5DigestAsHex((nowSubStr + shopId).getBytes());
                logger.info("Info=>checkSign=nowSubStr={}==sign={}", nowSubStr + shopId, newToken);
                if (newToken.equals(sign)) {
                    flag = true;
                }
            }

        } catch (Exception e) {
            logger.error("签名数据校验失败");
        }
        if (!flag) {
            return AjaxResult.error("签名数据校验失败");
        }

        HashMap<String, Object> resultMap = null;
        try {
            // 获取门店账单信息
            HashMap<String, Object> filterMap = new HashMap<>();
            filterMap.put("shopId", shopId);
            String atime = Convert.toStr(jsonObject.getOrDefault("atime", ""), "");
            if (StringUtils.isNotBlank(atime)) {
                DateTime atimeDate = DateUtil.beginOfMonth(DateUtil.parseDate(atime));
                atime = DateUtil.format(atimeDate, "yyyy-MM-dd");
            }
            filterMap.put("atime", atime);
            Map<String, Object> mapList = shopMapper.getShpBill(filterMap);
            JSONObject shopJson = JSON.parseObject(JSON.toJSONString(mapList));
            if (null == shopJson || shopJson.containsKey("rescode")) {
                return AjaxResult.error("门店当前月份的账单数据不存在");
            }
            resultMap = buildContent(shopJson, 3);
        } catch (IOException e) {
            return AjaxResult.error("执行失败，请联系管理人员");
        }
        return AjaxResult.success(resultMap.get("htmlText"));
    }

    public AjaxResult getShopRewardList(Integer shopId, String atime) {

        if (null == shopId || StringUtils.isBlank(atime)) {
            return AjaxResult.error("请求参数有误");
        }

        Map<String, Object> result = shopMapper.getShopReward(shopId);

        return AjaxResult.success(result);
    }

    public AjaxResult getFreeBillList(Integer shopId, String atime) {
        if (null == shopId || StringUtils.isBlank(atime)) {
            return AjaxResult.error("请求参数有误");
        }
        HashMap<String, Integer> paramMap = new HashMap<>();
        paramMap.put("shopId", shopId);
        List<Map<String, Object>> result = shopMapper.getFreeBillList(paramMap);

        return AjaxResult.success(result);
    }
}
